C ++ String (oder char *) in wstring (oder wchar_t *) konvertieren

string s = "おはよう"; wstring ws = FUNCTION(s, ws); 

Wie würde ich den Inhalt von s an ws zuweisen?

Nach Google gesucht und einige Techniken verwendet, aber sie können den genauen Inhalt nicht zuordnen. Der Inhalt ist verzerrt.

Solutions Collecting From Web of "C ++ String (oder char *) in wstring (oder wchar_t *) konvertieren"

Angenommen, die Eingabezeichenfolge in Ihrem Beispiel (お は よ う) ist eine UTF-8-Codierung (was nicht so aussieht, aber nehmen wir an, dass dies der Erklärung dient :-)) Darstellung einer Unicode-Zeichenfolge von Ihrem Interesse, dann kann Ihr Problem vollständig mit der Standardbibliothek (C ++ 11 und neuer) allein getriggers werden.

Die TL; DR-Version:

 #include  #include  #include  std::wstring_convert> converter; std::string narrow = converter.to_bytes(wide_utf16_source_string); std::wstring wide = converter.from_bytes(narrow_utf8_source_string); 

Längeres online kompilierbares und lauffähiges Beispiel:

(Sie alle zeigen das gleiche Beispiel. Es gibt nur einige für die Redundanz …)

Hinweis (alt) :

Wie in den Kommentaren erwähnt und in https://stackoverflow.com/a/17106065/6345 erläutert, gibt es Fälle, in denen die Verwendung der Standardbibliothek zur Konvertierung zwischen UTF-8 und UTF-16 zu unerwarteten Unterschieden bei den Ergebnissen auf verschiedenen Plattformen führt . Für eine bessere Konvertierung betrachten Sie std::codecvt_utf8 wie unter http://en.cppreference.com/w/cpp/locale/codecvt_utf8 beschrieben

Hinweis (neu) :

Da der codecvt Header in C ++ 17 veraltet ist, wurden einige Bedenken hinsichtlich der in dieser Antwort vorgestellten Lösung laut. Der C ++ – Standardausschuss fügte jedoch eine wichtige Aussage in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html hinzu

Diese Bibliothekskomponente sollte neben Anhang in Anhang D fallen, bis ein geeigneter Ersatz standardisiert ist.

In absehbarer Zukunft ist die codecvt Lösung in dieser Antwort also sicher und portabel.

 int StringToWString(std::wstring &ws, const std::string &s) { std::wstring wsTmp(s.begin(), s.end()); ws = wsTmp; return 0; } 

Ihre Frage ist unterspezifiziert. Genau genommen ist dieses Beispiel ein Syntaxerrors. Allerdings ist std::mbstowcs wahrscheinlich das, was Sie suchen.

Es ist eine C-Bibliothek-function und arbeitet mit Puffern, aber hier ist ein leicht zu bedienendes Idiom, mit freundlicher Genehmigung von TBohne (ehemals Mooing Duck):

 std::wstring ws(s.size(), L' '); // Overestimate number of code points. ws.resize(std::mbstowcs(&ws[0], s.c_str(), s.size())); // Shrink to fit. 

Nur Windows API, vor C ++ 11 Implementierung, falls jemand es benötigt:

 #include  #include  #include  using std::runtime_error; using std::string; using std::vector; using std::wstring; wstring utf8toUtf16(const string & str) { if (str.empty()) return wstring(); size_t charsNeeded = ::MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), NULL, 0); if (charsNeeded == 0) throw runtime_error("Failed converting UTF-8 string to UTF-16"); vector buffer(charsNeeded); int charsConverted = ::MultiByteToWideChar(CP_UTF8, 0, str.data(), (int)str.size(), &buffer[0], buffer.size()); if (charsConverted == 0) throw runtime_error("Failed converting UTF-8 string to UTF-16"); return wstring(&buffer[0], charsConverted); } 

Wenn Sie Windows / Visual Studio verwenden und eine Zeichenfolge in wstring konvertieren müssen, können Sie Folgendes verwenden:

 #include  #include  ... string s = "some string"; CA2W ca2w(s.c_str()); wstring w = ca2w; printf("%s = %ls", s.c_str(), w.c_str()); 

Gleiches Verfahren zum Konvertieren eines wstring in einen String (manchmal müssen Sie eine Codepage angeben):

 #include  #include  ... wstring w = L"some wstring"; CW2A cw2a(w.c_str()); string s = cw2a; printf("%s = %ls", s.c_str(), w.c_str()); 

Sie könnten eine Codepage und sogar UTF8 angeben (das ist ziemlich nett, wenn Sie mit JNI / Java arbeiten ).

 CA2W ca2w(str, CP_UTF8); 

Wenn Sie mehr über Codepages wissen wollen, gibt es einen interessanten Artikel über Joel auf Software: Das absolute Minimum, das jeder Softwareentwickler unbedingt, unbedingt über Unicode und Zeichensätze wissen muss .

Diese CA2W-Makros (Convert Ansi in Wide = Unicode) sind Teil von ATL- und MFC-String-Konvertierungs-Makros , einschließlich Samples.

Manchmal müssen Sie die Sicherheitswarnung # 4995 ‘deaktivieren, ich kenne keine andere Problemumgehung (für mich passiert es, wenn ich für Windows XP in VS2012 kompiliert habe).

 #pragma warning(push) #pragma warning(disable: 4995) #include  #include  #pragma warning(pop) 

Edit: Nun, nach diesem Artikel scheint der Artikel von Joel zu sein: “Während unterhaltsam, ist es ziemlich leicht auf tatsächliche technische Details”. Artikel: Was jeder Programmierer absolut, positiv über Kodierung und Zeichensätze wissen muss, um mit Text zu arbeiten .

Von char* zu wstring :

 char* str = "hello worlddd"; wstring wstr (str, str+strlen(str)); 

Von string zu wstring :

 string str = "hello worlddd"; wstring wstr (str.begin(), str.end()); 

Beachten Sie, dass das nur funktioniert, wenn die zu konvertierende Zeichenfolge nur ASCII-Zeichen enthält.

Hier ist eine Möglichkeit, wstring , wstring und Mixed-String-Konstanten mit wstring zu wstring . Verwenden Sie die class wstringstream .

 #include  std::string narrow = "narrow"; std::wstring wide = "wide"; std::wstringstream cls; cls < < " abc " << narrow.c_str() << L" def " << wide.c_str(); std::wstring total= cls.str(); 

mit Boost.Locale:

 ws = boost::locale::conv::utf_to_utf(s); 

Diese Variante ist mein Favorit im wirklichen Leben. Es konvertiert die Eingabe, wenn es UTF-8 ist, in die entsprechende wstring . Wenn die Eingabe beschädigt ist, wird die wstring aus den einzelnen Bytes aufgebaut. Dies ist sehr hilfreich, wenn Sie sich über die Qualität Ihrer Eingabedaten nicht sicher sein können.

 std::wstring convert(const std::string& input) { try { std::wstring_convert> converter; return converter.from_bytes(input); } catch(std::range_error& e) { size_t length = input.length(); std::wstring result; result.reserve(length); for(size_t i = 0; i < length; i++) { result.push_back(input[i] & 0xFF); } return result; } } 

Methode s2ws funktioniert gut. Hoffnung hilft.

 std::wstring s2ws(const std::string& s) { std::string curLocale = setlocale(LC_ALL, ""); const char* _Source = s.c_str(); size_t _Dsize = mbstowcs(NULL, _Source, 0) + 1; wchar_t *_Dest = new wchar_t[_Dsize]; wmemset(_Dest, 0, _Dsize); mbstowcs(_Dest,_Source,_Dsize); std::wstring result = _Dest; delete []_Dest; setlocale(LC_ALL, curLocale.c_str()); return result; } 

Basierend auf meinen eigenen Tests (auf Windows 8, vs2010) kann mbstowcs tatsächlich die ursprüngliche Zeichenfolge beschädigen, es funktioniert nur mit der ANSI-Codepage. Wenn MultiByteToWideChar / WideCharToMultiByte auch Zeichenfolgenbeschädigungen verursachen kann – sie ersetzen jedoch Zeichen, die sie nicht kennen, durch “?” Fragezeichen, aber mbstowcs neigt dazu anzuhalten, wenn es auf unbekannte Zeichen stößt und an genau diesem Punkt die Zeichenfolge schneidet. (Ich habe vietnamesische Zeichen auf finnischen Fenstern getestet).

Also lieber Multi * -Fenster api-function gegenüber analogen ansi C-functionen.

Auch was ich am kürzesten bemerkt habe, um eine Zeichenfolge von einer Codepage zu einer anderen zu codieren, ist nicht die Verwendung von MultiByteToWideChar / WideCharToMultiByte API-functionsaufrufen, sondern deren analoge ATL-Makros: W2A / A2W.

Die analoge function würde also wie folgt lauten:

 wstring utf8toUtf16(const string & str) { USES_CONVERSION; _acp = CP_UTF8; return A2W( str.c_str() ); } 

_acp wird im USES_CONVERSION-Makro deklariert.

Oder auch eine function, die ich oft vermisse, wenn ich eine alte Datenkonvertierung in eine neue umwandele:

 string ansi2utf8( const string& s ) { USES_CONVERSION; _acp = CP_ACP; wchar_t* pw = A2W( s.c_str() ); _acp = CP_UTF8; return W2A( pw ); } 

Aber bitte beachten Sie, dass diese Makros stark stapeln – verwenden Sie keine for-Schleifen oder rekursive Schleifen für die gleiche function – nach der Verwendung von W2A oder A2W-Makro – besser so schnell wie möglich zurückzukehren, damit Stapel von vorübergehender Konvertierung befreit wird.

string s = "おはよう"; ist ein Fehler.

Sie sollten wstring direkt verwenden:

 wstring ws = L"おはよう"; 

Verwenden Sie diesen Code, um Ihre Zeichenfolge in wstring zu konvertieren

 std::wstring string2wString(const std::string& s){ int len; int slength = (int)s.length() + 1; len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0); wchar_t* buf = new wchar_t[len]; MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len); std::wstring r(buf); delete[] buf; return r; } int main(){ std::wstring str="your string"; std::wstring wStr=string2wString(str); return 0; }