C++でCSVがutf8でもshiftjisでもshiftjisのデータとして読み込めるクラス

#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <locale>
#include <codecvt>

class CSVReader {
public:
    CSVReader(const std::string& filename) : filename_(filename) {}

    bool ReadCSV(std::vector<std::vector<std::string>>& data) {
        std::ifstream file(filename_);
        if (!file.is_open()) {
            std::cerr << "Failed to open file: " << filename_ << std::endl;
            return false;
        }

        std::string line;
        while (std::getline(file, line)) {
            // 自動的にエンコーディングを検出して変換
            std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> utf8_converter;
            std::wstring_convert<std::codecvt<wchar_t, char, std::mbstate_t>> sjis_converter;
            std::wstring wline;

            try {
                wline = utf8_converter.from_bytes(line);
            } catch (const std::exception& e) {
                try {
                    wline = sjis_converter.from_bytes(line);
                } catch (const std::exception& e) {
                    std::cerr << "Failed to convert line to UTF-8 or Shift-JIS: " << e.what() << std::endl;
                    return false;
                }
            }

            // CSVデータをパースして格納
            std::vector<std::string> row;
            std::wstring cell;
            bool inQuotes = false;

            for (wchar_t c : wline) {
                if (c == L'"') {
                    inQuotes = !inQuotes;
                } else if (c == L',' && !inQuotes) {
                    row.push_back(utf8_converter.to_bytes(cell));
                    cell.clear();
                } else {
                    cell += c;
                }
            }

            row.push_back(utf8_converter.to_bytes(cell));
            data.push_back(row);
        }

        file.close();
        return true;
    }

private:
    std::string filename_;
};

int main() {
    std::vector<std::vector<std::string>> csvData;
    CSVReader reader("example.csv");

    if (reader.ReadCSV(csvData)) {
        // データを使って何かを行う
        for (const auto& row : csvData) {
            for (const auto& cell : row) {
                std::cout << cell << "\t";
            }
            std::cout << std::endl;
        }
    }

    return 0;
}

C++でエンコード自動判断関数

#include <fstream>
#include <iostream>
#include <vector>

// エンコーディングを判断するための関数
std::string GetFileEncoding(const std::string& filePath) {
    std::ifstream file(filePath, std::ios::binary);
    if (!file) {
        return "Unknown";
    }

    std::vector<unsigned char> buffer(4);
    file.read(reinterpret_cast<char*>(&buffer[0]), 4);

    if (file.gcount() >= 2) {
        if (buffer[0] == 0xEF && buffer[1] == 0xBB && buffer[2] == 0xBF) {
            return "UTF-8";
        } else if (buffer[0] == 0xFF && buffer[1] == 0xFE) {
            return "UTF-16LE";
        } else if (buffer[0] == 0xFE && buffer[1] == 0xFF) {
            return "UTF-16BE";
        }
    }

    // デフォルトエンコーディング(例: Shift-JIS)を判断するための追加のロジックをここに追加できます

    return "Shift-JIS";
}

int main() {
    std::string csvFilePath = "your_csv_file.csv";

    std::string encoding = GetFileEncoding(csvFilePath);
    std::cout << "File Encoding: " << encoding << std::endl;

    return 0;
}

C#でCSVのエンコードを自動判定して読み込む

.NET Core 3.0以降、Shift-JISエンコーディング(コードページ932)はデフォルトでサポートされなくなりました。そのため、カスタムエンコーディングプロバイダーを登録する必要があります。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

class Program
{
    static void Main()
    {
        string csvFilePath = "your_csv_file.csv";

        // カスタムエンコーディングプロバイダーを登録
        Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

        // ファイルのエンコーディングを判断する
        Encoding encoding = GetFileEncoding(csvFilePath);

        // CSVファイルを読み込む
        var lines = File.ReadAllLines(csvFilePath, encoding).Skip(1); // ヘッダーをスキップ

        foreach (var line in lines)
        {
            var values = line.Split(',');
            string code = values[0].Trim();
            string name = values[1].Trim();
            string market = values[2].Trim();
            string type = values[3].Trim();

            // ここでcode、name、market、typeを使用できます
        }
    }

    static Encoding GetFileEncoding(string filePath)
    {
        // ファイルの先頭からバイトを読み取り、エンコーディングを判断する
        byte[] bom = new byte[4];
        using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
        {
            fileStream.Read(bom, 0, 4);
        }

        if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF)
        {
            return Encoding.UTF8;
        }
        else if (bom[0] == 0xFF && bom[1] == 0xFE)
        {
            return Encoding.Unicode; // UTF-16 LE
        }
        else if (bom[0] == 0xFE && bom[1] == 0xFF)
        {
            return Encoding.BigEndianUnicode; // UTF-16 BE
        }
        else
        {
            return Encoding.GetEncoding(932); // Shift-JIS
        }
    }
}

フォルダ内のすべてのJPEG/PNG画像に1ピクセルの黒い枠を追加するためのPythonコード

windows環境用

実行フォルダにあるjpegすべてに1ドットの黒いフチを付けます

# -*- coding: cp932 -*-
from PIL import Image
import os

def add_border_to_images_in_current_folder():
    # カレントディレクトリを取得
    current_folder = os.getcwd()

    # カレントディレクトリ内のすべてのファイルをチェック
    for filename in os.listdir(current_folder):
        # Shift-JISでエンコードされたファイル名を扱う
        filename_shiftjis = filename.encode('cp932').decode('cp932')

        if filename_shiftjis.lower().endswith('.jpg') or filename_shiftjis.lower().endswith('.jpeg'):
            file_path = os.path.join(current_folder, filename_shiftjis)
            
            # 画像を開く
            with Image.open(file_path) as img:
                # 画像のサイズを取得
                width, height = img.size
                
                # 新しい画像サイズ(元のサイズ + 2ピクセル)
                new_width = width + 2
                new_height = height + 2
                
                # 新しい画像を作成(黒い背景)
                new_img = Image.new("RGB", (new_width, new_height), "black")
                
                # 元の画像を中央に配置
                new_img.paste(img, (1, 1))
                
                # 画像を保存(元のファイル名で上書き)
                new_img.save(file_path)

add_border_to_images_in_current_folder()


こちらはPNG用。透明は維持。

# -*- coding: cp932 -*-
from PIL import Image
import os

def add_black_border_to_png_images_in_current_folder():
    # カレントディレクトリを取得
    current_folder = os.getcwd()

    # カレントディレクトリ内のすべてのファイルをチェック
    for filename in os.listdir(current_folder):
        if filename.lower().endswith('.png'):
            file_path = os.path.join(current_folder, filename)
            
            # 画像を開く
            with Image.open(file_path) as img:
                # 画像のサイズを取得
                width, height = img.size
                
                # 新しい画像サイズ(元のサイズ + 2ピクセル)
                new_width = width + 2
                new_height = height + 2
                
                # 新しい画像を作成(黒い背景のRGBA画像)
                new_img = Image.new("RGBA", (new_width, new_height), (0, 0, 0, 255))
                
                # アルファチャンネルを取得(存在する場合)
                if img.mode in ('RGBA', 'LA'):
                    mask = img.split()[-1]
                else:
                    mask = None

                # 元の画像を中央に配置
                new_img.paste(img, (1, 1), mask)
                
                # 画像を保存(元のファイル名で上書き)
                new_img.save(file_path)

add_black_border_to_png_images_in_current_folder()

ポインタで渡されたクラスが継承された子クラスかの判定方法 MFC

C++でポインタ経由で渡されたクラスが特定の子クラスであるかを判定するには、dynamic_castを使用します。dynamic_castは実行時に型の安全なキャストを行い、指定した型へのキャストが不可能な場合はnullptrを返します。これを利用して、ポインタが特定の子クラスのインスタンスを指しているかをチェックできます。

例えば、BaseクラスのポインタbasePtrが、Derivedクラスのインスタンスを指しているかどうかをチェックするには、次のように書きます。

Base* basePtr;  // 何らかの方法で初期化されている
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr);

if (derivedPtr != nullptr) {
    // basePtrはDerivedクラスのインスタンスを指している
} else {
    // basePtrはDerivedクラスのインスタンスを指していない
}

ここで、dynamic_castはポリモーフィズムをサポートするために、クラスが少なくとも1つの仮想関数を持っている必要があります(通常はデストラクタが仮想です)。また、dynamic_castは実行時の型チェックを行うため、コンパイル時ではなく実行時にタイプ安全を確保します。

visual studio 2022 同じソリューションに.Net Frameworkと .Net Core のクラスライブラリプロジェクトがあるとデバッガが混乱する 

.Net Frameworkのプロジェクトでデバッグしようとしたら 以下のエラーがでた

致命的なエラーが発生しました。デバッグを終了する必要があります。
デバッガーは、Desktop CLR (.NET Framework) マネージド デバッガーを使用するように構成されていますが、
ターゲット プロセスは CoreCLR (.NET Core) ランタイムを読み込みました。このプロジェクトをデバッグするには、
'マネージド (CoreCLR)' デバッガーを使用するように構成してください。

クラスライブラリなのでそもそもデバッガーの指定がない。

.Net Coreのプロジェクトのフォルダ名をかえちゃうなど
一時的に.Net Coreプロジェクトを読み込めないようにしたらなおった。

めんどいけどレアケースってことなんでしょう。

HTML JAVAScript コンテンツをランダムでどっちかだけ出す(A/B)

<!DOCTYPE html>
<html>
<head>
    <title>ページのタイトル</title>
</head>
<body>
    <!-- ページのコンテンツ -->

    <div id="contentA">コンテンツA</div>
    <div id="contentB">コンテンツB</div>

    <script>
        document.addEventListener("DOMContentLoaded", function() {
            var contentA = document.getElementById('contentA');
            var contentB = document.getElementById('contentB');

            var random = Math.floor(Math.random() * 2);

            if (random === 0) {
                contentA.style.display = 'block';
                contentB.style.display = 'none';
            } else {
                contentA.style.display = 'none';
                contentB.style.display = 'block';
            }
        });
    </script>
</body>
</html>

window.onload より
window.addEventListener("DOMContentLoaded", function() { ... }) を使用する方が良い場合があります。
window.onload と比較して、いくつかの利点があります。

速度: DOMContentLoaded イベントは、HTML が完全に読み込まれて解析された時点で発生しますが、スタイルシート、画像、サブフレームの読み込みは待ちません。一方、window.onload はページ上の全てのリソース(画像、スタイルシート、スクリプトなど)の読み込みが完了した後に発火します。そのため、DOMContentLoaded を使用した方がページがより早くインタラクティブになります。

柔軟性: 複数の DOMContentLoaded リスナーをページに追加できますが、window.onload を複数設定すると、前の設定を上書きしてしまう可能性があります。

python TOPIX500の銘柄を公式のPDFから抽出する

www.jpx.co.jp
ここの構成銘柄別ウエイト一覧のcsvが2023/9末で更新止まってしまってる

2023/11/8現在
TOPIXニューインデックスシリーズ定期選定結果(2023年10月31日)にあるpdfにだけまとまってたのでそこからとってみた

import pdfplumber

# PDFファイルのパス
pdf_path = r'C:\Users\hogehoge\Desktop\mei2_12_size.pdf'


# 3. 構成銘柄一覧以下のテーブルからTOPIX500の銘柄のみを抽出
with pdfplumber.open(pdf_path) as pdf:
    # テーブルが始まるページを見つけるためのフラグ
    table_started = False
    # PDFの各ページを順に処理
    for page in pdf.pages:
        # ページ内のテキストを取得
        text = page.extract_text()
        # 特定のテキストがページに含まれているかチェックし、テーブルが始まるページを特定
        if '3. 構成銘柄一覧' in text:
            table_started = True
        # テーブルが始まった後、続くページからテーブルデータを抽出
        if table_started:
            # ページ内のテーブルを抽出
            tables = page.extract_tables()
            for table in tables:
                # テーブルの各行を処理
                for row in table:
                    # 最後の列が指定されたテキストのいずれかを含むかチェック
                    if row[-1] in ['TOPIX Core30', 'TOPIX Large70', 'TOPIX Mid400']:
                        print(row[1], row[2])  # ここでのrow[1]はコード、row[2]は銘柄名を指す

C# edgeの指定タイトルもウインドウを探して、アドレスバーを取得して返す関数

   /// <summary>
   /// 指定文字が含まれたEdgeウィンドウを監視して、URLを取得する
   /// </summary>
   /// <param name="sTitle"></param>
   /// <returns></returns>
   private static string MonitorEdgeWindowsForUrl(string sTitle = "127.0.0.1")
   {

       using var automation = new UIA3Automation();
       string foundUrl = null;

       while (foundUrl == null)
       {
           try
           {
               // "msedge" プロセス名を持つすべてのプロセスを取得
               var edgeProcesses = Process.GetProcessesByName("msedge");

               // msedge プロセスが存在しない場合、"" を返す
               if (edgeProcesses.Length == 0)
               {
                   return "";
               }

               foreach (var process in edgeProcesses)
               {
                   if (process.MainWindowHandle != IntPtr.Zero)
                   {
                       var windowElement = automation.FromHandle(process.MainWindowHandle);

                       // ウィンドウタイトルに 指定文字列 が含まれているか確認
                       if (windowElement.Name.Contains(sTitle))
                       {
                           // アドレスバーを取得
                           var addressBar = windowElement.FindFirstDescendant(cf => cf.ByControlType(ControlType.Edit));
                           if (addressBar != null)
                           {
                               foundUrl = addressBar.AsTextBox().Text;
                               Console.WriteLine($"URL: {foundUrl}");
                           }
                           else
                           {
                               Console.WriteLine("アドレスバーが見つかりませんでした。");
                           }

                           // ウィンドウを閉じる
                           windowElement.AsWindow().Close();

                           // ループ抜ける
                           break;
                       }
                   }
               }

           }
           catch (Exception ex)
           {
               Console.WriteLine($"Error processing window: {ex.Message}");
           }


           // Wait for a short duration before checking again
           System.Threading.Thread.Sleep(100);
       }

       return foundUrl;