C++勉強メモ(文字コード変換&改行コード)
文字コード変換と改行コード周りで勉強したことをメモ。Windowsだけ、あるいはLinuxだけ使うならあまり考えなくてもよいが、両方対応しようとしたらちょっと面倒だったのでメモしておく。なお、本稿途中のコードでは、最後に掲載するコードをライブラリとして使っている。
UTF8のテキストを文字化けなくコンソールに出力する
Windowsだと多くの環境では文字化けするのでSJISに直す(ふと思ったが、海外版のWindowsだったらデフォルトエンコーディングどうなってるんだろう、、)。
utf8_to_term_enc(line)
Powershell Core (v.7.1.3)なら
[console]::OutputEncoding = New-Object System.Text.UTF8Encoding
とすればUTF8でも文字化けしないが、SJISで出力しておいた方が無難だろう。
ちなみに、コマンドプロンプトやWindows Powershellのときはchcp 65001
と入力するとUTF8を文字化けなく表示できる。
getlineの出力をtrimする
改行コードがCRLFのテキストをgetlineで読み込むと、Linuxの場合最後に'\r'がつくのでこれをtrimする。
std::ifstream input_file("input-utf8.txt"); std::string line; while (getline_rtrim(input_file, line)) { cout << line << endl; }
上2つの合わせ技
UTF8のテキストを読込&ターミナルに出力する場合は、以下のようにしておけばWindows, Linuxで同じ結果が得られる。
std::ifstream input_file("input-utf8.txt"); std::string line; while (getline_rtrim(input_file, line)) { cout << utf8_to_term_enc(line) << endl; }
LinuxでBOM付きのUTF-8を出力する
計算結果をCSVファイルに出力する際、LinuxだとエンコーディングがUTF-8になってしまいExcelで開くと文字化けする。これを防止するために、CSVファイルの最初にBOMをいれる。
std::ofstream ofs("result.csv");
add_utf8_bom(ofs);
ライブラリでは、Linuxの場合ICUを使ってUTF8⇔SJIS変換を行うようにしているので、こっちを使ってもよいかも。
utf8_to_sjis("utf8 string"); sjis_to_utf8("sjis string");
210811_追記
ICUを使うと文字エンコーディングの判定ができたのでライブラリに入れてみた。
auto results = chardet("エンコーディングが判定できるくらい長い文章を入れる").value(); cout << "Detected encoding: " << results.enc << ", " << results.confidence << endl; // Detected encoding: UTF-8, 100