2016-05-29 18 views
3

C++ 11には、/からUTF8表現にstd::wstringワイド文字の文字列を変換するツールがあります:std::codecvtstd::codecvt_utf8std::codecvt_utf8_utf16などの変換C++のstd :: wstringのにUTF8でのstd :: codecvt_xxx

1がで利用可能です通常のワイド文字のWindows文字列std::wstringをutf8に変換するWindowsアプリstd::string?ロケールを設定しないと常に動作しますか?

+1

可能な重複UTF-8でエンコードされた文字列へのwstring](http://stackoverflow.com/questions/4358870/convert-wstring-to-string-encoded-in-utf-8) – IInspectable

+0

@IInspあなたはあなたが言及したページを読んだ後にこの質問を投稿しました)))そのページの私の質問に対する明確な答えが表示されない –

+1

[this](http://stackoverflow.com/a/12903901/1889329)質問? [コメント](http://stackoverflow.com/questions/4358870/convert-wstring-to-string-encoded-in-utf-8#comment32601904_12903901)*「[t]彼がVS2012を使用している場合、Windows用の作品または後で "*。 – IInspectable

答えて

1

std::codecvt_utf8が変換のためにうまくいくようです。std::wstring - >utf8です。それはすべての私のテストに合格した。 (Windowsアプリケーション、Visual Studio 2015、ENロケールのWindows 8)

ファイル名をUTF8に変換する方法が必要でした。したがって、私のテストはファイル名に関するものです。

私のアプリでは、ファイルパスを処理するためにboost::filesystem::path 1.60.0を使用しています。うまく動作しますが、ファイル名をUTF8に正しく変換することはできません。 内部的にWindowsのバージョンboost::filesystem::pathは、ファイルパスを格納するためにstd::wstringを使用します。残念ながら、std::stringへのビルドイン変換は正しく動作しません。

テストケース:

  • は、混合シンボルc:\test\皀皁皂皃的(いくつかのランダムなアジアのシンボル)boost::filesystem::directory_iterator
  • スキャンディレクトリとファイルを作成
  • は、ビルドインを経由してstd::stringに変換したファイルのboost::filesystem::pathを取得変換filenamePath.string()
  • あなたはc:\test\?????を取得します。アジアのシンボルは「?」に変換されます。良くない。

boost::filesystemは、std::codecvtを内部で使用します。変換のためには機能しませんstd::wstring - >std::string

代わりのビルドでboost::filesystem::path変換あなたは、このよう(original snippet)を変換関数を定義することができます。

std::string utf8_to_wstring(const std::wstring & str) 
{ 
    std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv; 
    return myconv.to_bytes(str); 
} 

その後、あなたは簡単にUTF8にファイルパスを変換することができます:utf8_to_wstring(filenamePath.wstring())。それは完全に動作します。

すべてのファイルパスで機能します。 ASCII文字列c:\test\test_file、アジア系文字列c:\test\皀皁皂皃的、ロシア語文字列c:\test\абвгд、混合文字列c:\test\test_皀皁皂皃的c:\test\test_абвгдc:\test\test_皀皁皂皃的_абвгдをテストしました。すべての文字列に対して、有効なUTF8表現を受け取ります。

4

どのように変換するかによって異なります。
ソースエンコーディングタイプとターゲットエンコーディングタイプを指定する必要があります。
wstringはフォーマットではなく、データタイプを定義するだけです。

は今、通常、1つは1つが何Microsoft Windowsの用途であるUTF16を意味し、「Unicodeを」と言うとき、それはwstringが含まれていusuaslyものです。

ので、UTF8からUTF16に変換するための正しい方法:

 std::string utf8String = "blah blah"; 

    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert; 
    std::wstring utf16String = convert.from_bytes(utf8String); 

そして、他の方法で回避:

 std::wstring utf16String = "blah blah"; 

    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> convert; 
    std::string utf8String = convert.to_bytes(utf16String); 

と混乱に追加する:あなたは上std::stringを使用する場合
ウィンドウプラットフォーム(マルチバイトコンパイルを使用する場合など)、UTF8ではありません。彼らはANSIを使用します。
具体的には、Windowsが使用しているデフォルトのエンコーディング言語です。

また、wstring is not exactly the same as UTF-16に注意してください。 UnicodeでのWindows APIコマンドをコンパイル

は、これらのフォーマットを期待:

コマンド - マルチバイトからANSI
コマンドW - ユニコード - [変換のUTF16

+0

* "通常、" Unicode "と言うと、1つはUTF16" * - Uhmを意味します。 "Unicode"と言うと、私はUnicodeを知っていて、標準を混乱させたくないと思います。 * "std :: stringをWindowsプラットフォームで使用すると、UTF8ではなく、ANSIを使用します。* - ' std :: string'で使用される文字エンコーディングは実装(つまりコンパイラ)によって決まります。 、ターゲットプラットフォームではありません。 Windows上で 'std :: string'に対してUTF-8エンコーディングを使用するコンパイラを書くことができます。 – IInspectable

関連する問題