2016-05-29 136 views
3

C++ 11具有工具轉換寬字符串std::wstring從/到UTF8表示:std::codecvtstd::codecvt_utf8std::codecvt_utf8_utf16轉換C++的std :: wstring的爲UTF8與標準:: codecvt_xxx

哪一個是可用由Windows應用程序將常規寬字符Windows字符串std::wstring轉換爲utf8 std::string?它總是工作沒有配置區域設置?

+1

的可能的複製[轉換wstring以UTF-8編碼的字符串](http://stackoverflow.com/questions/4358870/convert-wstring-to-string-encoded-in-utf-8) – IInspectable

+0

@IInsp ectable我讀過你提到的頁面後發佈了這個問題)))我沒有看到一個明確的答案我的問題在該頁 –

+1

是否[this](http://stackoverflow.com/a/12903901/1889329)不回答您的問題題?根據[評論](http://stackoverflow.com/questions/4358870/convert-wstring-to-string-encoded-in-utf-8#comment32601904_12903901)*「[t]他的作品爲Windows,如果您使用VS2012或更高版本「*。 – IInspectable

回答

1

似乎std::codecvt_utf8適用於轉換std::wstringutf8。它通過了我所有的測試。 (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文件,得到boost::filesystem::path的文件
  • 它通過內置的轉換爲std::string轉換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不是一種格式,它只是定義了一種數據類型。

現在通常當一個人說「統一」,一個是指UTF16這是什麼的Microsoft Windows用途,那就是usuasly什麼wstring包含。

所以,正確的方式轉換從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「時,一個意思是UTF16」* - 嗯......當有人說「Unicode」時,我希望人們知道Unicode,並且不會將標準與任意編碼混淆。 *「當在Windows平臺上使用std :: string時,它不是UTF8,它們使​​用ANSI。」* - 用於std :: string的字符編碼由實現(即編譯器) ,而不是目標平臺。你可以編寫一個編譯器,在Windows上爲'std :: string'使用UTF-8編碼。 – IInspectable