2016-05-29 14 views
3

C++ 11 hat Tools breite char-Strings konvertieren std::wstring von/nach UTF-8-Darstellung: std::codecvt, std::codecvt_utf8, std::codecvt_utf8_utf16 usw.Konvertieren von C++ std :: wstring auf UTF-8 mit std :: codecvt_xxx

Welches verwendbar ist durch Windows app zum Konvertieren von regulären breiten Zeichen Windows-Strings std::wstring zu utf8 std::string? Funktioniert es immer, ohne Gebietsschemata zu konfigurieren?

+1

Mögliche Duplikat [Umrechnen wstring to string codiert in UTF-8] (http://stackoverflow.com/questions/4358870/convert-wstring-to-string-encoded-in-utf-8) – IInspectable

+0

@IInnsp ectable Ich habe diese Frage gepostet, nachdem ich die Seite gelesen habe, die Sie erwähnt haben))) Ich sehe keine klare Antwort auf meine Frage auf dieser Seite –

+1

Beantwortet [this] (http://stackoverflow.com/a/12903901/1889329) nicht Ihre Frage? Laut einem [Kommentar] (http://stackoverflow.com/questions/4358870/convert-wstring-to-string-encoded-in-utf-8#comment32601904_12903901) * "[t] arbeitet er für Windows, wenn Sie VS2012 verwenden oder später"*. – IInspectable

Antwort

1

Scheint, dass std::codecvt_utf8 funktioniert gut für die Konvertierung std::wstring ->utf8. Es hat alle meine Tests bestanden. (Windows app, Visual Studio 2015, Windows 8 mit EN locale)

Ich brauchte einen Weg, um Dateinamen in UTF8 zu konvertieren. Daher geht es bei meinem Test um Dateinamen.

In meiner App verwende ich boost::filesystem::path 1.60.0, um mit Dateipfad umzugehen. Es funktioniert gut, aber nicht in der Lage, Dateinamen in UTF8 richtig zu konvertieren. Intern Windows-Version von boost::filesystem::path verwendet std::wstring, um den Dateipfad zu speichern. Die Build-In-Konvertierung zu std::string funktioniert leider nicht.

Testfall:

  • erstellen Datei mit gemischten Symbolen c:\test\皀皁皂皃的 (einige zufällige asiatischen Symbole)
  • Scan dir mit boost::filesystem::directory_iterator, erhalten boost::filesystem::path für die Datei
  • wandeln es in der std::string über build-in Umwandlung filenamePath.string()
  • erhalten Sie c:\test\?????. Asiatische Symbole wurden in "?" Umgewandelt. Nicht gut.

boost::filesystem verwendet intern std::codecvt. Es funktioniert nicht für die Konvertierung std::wstring ->std::string.

Statt build-in boost::filesystem::path Konvertierung können Sie Konvertierungsfunktion als dieser (original snippet) definieren:

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

Dann können Sie Dateipfad zu UTF8 konvertieren leicht: utf8_to_wstring(filenamePath.wstring()). Es funktioniert perfekt.

Es funktioniert für jeden Dateipfad. Ich testete ASCII-Zeichenfolgen c:\test\test_file, asiatische Zeichenfolgen c:\test\皀皁皂皃的, russische Zeichenfolgen c:\test\абвгд, gemischte Zeichenfolgen c:\test\test_皀皁皂皃的, c:\test\test_абвгд, c:\test\test_皀皁皂皃的_абвгд. Für jede Zeichenfolge erhalte ich eine gültige UTF8-Darstellung.

4

Hängt davon ab, wie Sie sie konvertieren.
Sie müssen den Quellcodierungstyp und den Zielcodierungstyp angeben.
wstring ist kein Format, es definiert nur einen Datentyp.

Jetzt in der Regel, wenn man sagt „Unicode“, ein Mittel UTF16 das ist, was Microsoft Windows Anwendungen, und das ist, was usuasly wstring enthält.

also der richtige Weg von UTF8 in UTF16 zu konvertieren:

 std::string utf8String = "blah blah"; 

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

Und umgekehrt:

 std::wstring utf16String = "blah blah"; 

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

Und um die Verwirrung hinzuzufügen:
Wenn Sie std::string verwenden auf a Windows Plattform (wie wenn Sie eine Multibyte-Compilation verwenden), ist es nicht UTF8. Sie verwenden ANSI.
Genauer gesagt, die Standardcodierungssprache, die Ihre Windows verwendet.

Beachten Sie auch, dass wstring is not exactly the same as UTF-16.

Wenn in Unicode die Befehle Windows-API Kompilieren erwarten diese Formate:

Befehl A - multibyte-ANSI
Befehl W - Unicode-UTF16

+0

* "normalerweise, wenn man" Unicode "sagt, meint man UTF16" * - Uhm ... Wenn man "Unicode" sagt, würde ich hoffen, dass man Unicode kennt und den Standard nicht mit einer beliebigen Kodierung verwechselt. * "Wenn Sie std :: string auf einer Windows-Plattform verwenden [...], ist es NICHT UTF8. Sie verwenden ANSI." * - Die für 'std :: string' verwendete Zeichencodierung wird von der Implementierung (dh dem Compiler) bestimmt , nicht die Zielplattform. Sie können einen Compiler schreiben, der die UTF-8-Codierung für 'std :: string 'unter Windows verwendet. – IInspectable