C ++の文字列を使用したクロスプラットフォーム作業

少し前まで、C ++アプリケーションの文字列を使用したクロスプラットフォーム作業の問題に戸惑っていました。 タスクは、大まかに言って、あらゆるプラットフォームのあらゆるエンコーディングの部分文字列の大文字と小文字を区別しない検索として設定されました。



だから、私が最初に理解しなければならなかったことは、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を使用する場合の問題については説明しません。すべてが文書化されています。



All Articles