だから、私が最初に理解しなければならなかったことは、UTF-8エンコーディングとタイプstd :: stringでLinuxの文字列を操作する必要があることであり、Windowsでは行はUTF-16LE(タイプstd :: wstring)でなければなりません。 なんで? オペレーティングシステムの設計によるものだからです。 1つのwchar_t文字は4バイト(Windowsでは2バイト)を必要とするため、Linuxで文字列をstd :: wstringに格納するのは非常に高価です。Windows98ではWindowsでの作業にstd ::文字列が必要です。 :
#ifdef _WIN32 typedef std::wstring mstring; #else typedef std::string mstring; #endif // _WIN32
2番目は、テキストを任意のエンコーディングからmstring型に変換するタスクです。 多くのオプションはありません。 最初のオプションは、std ::ロケールおよびその他の関連する標準的なものを使用することです。 各文字セットを検索する必要性にすぐに対応するロケール(エンコーディング "windows-1251"はロケールRussian_Russia.1251などに対応するなど)。 そのようなテーブルは標準ライブラリには見つかりませんでした(おそらく見栄えが悪いのでしょうか?)。ロケールのリストのローションを探したくありませんでした。 とにかく、C ++でロケールを操作することは、私の意見では非常に明白ではありません。 フォーラムは、 libiconvまたはicuライブラリーの使用を推奨しました。 libiconvは非常に簡単でシンプルに見え、任意の文字セットからmstringに完全にトランスコードする仕事をしましたが、mstringを小文字に変換することになると失敗しました。 libiconvはこれを行う方法を知らないことが判明しましたが、Linuxでutf8文字列を小文字に簡単に美しく変換することはできませんでした。 そのため、選択はicuに委ねられ、すべてのタスク(変換と小文字の変換)を立派に解決しました。 icuライブラリを使用したプラットフォームに依存しないトランスコーディング手順は次のようになります。
std::string to_utf8(const std::string& source_str, const std::string& charset, bool lowercase) { const std::string::size_type srclen = source_str.size(); std::vector<UChar> target(srclen); UErrorCode status = U_ZERO_ERROR; UConverter *conv = ucnv_open(charset.c_str(), &status); if (!U_SUCCESS(status)) return std::string(); int32_t len = ucnv_toUChars(conv, target.data(), srclen, source_str.c_str(), srclen, &status); if (!U_SUCCESS(status)) return std::string(); ucnv_close(conv); UnicodeString ustr(target.data(), len); if (lowercase) ustr.toLower(); std::string retval; ustr.toUTF8String(retval); return retval; }
WindowsでUnicodeを使用する場合の問題については説明しません。すべてが文書化されています。