string s = "おはよう";
wstring ws = FUNCTION(s, ws);
Wie würde ich den Inhalt von s ws zuweisen?
Google gesucht und einige Techniken verwendet, aber sie können den genauen Inhalt nicht zuordnen. Der Inhalt ist verzerrt.
Samir
string s = "おはよう";
wstring ws = FUNCTION(s, ws);
Wie würde ich den Inhalt von s ws zuweisen?
Google gesucht und einige Techniken verwendet, aber sie können den genauen Inhalt nicht zuordnen. Der Inhalt ist verzerrt.
Johann Gell
Angenommen, die Eingabezeichenfolge in Ihrem Beispiel (おはよう) ist eine UTF-8-codierte Darstellung einer Unicode-Zeichenfolge (was dem Anschein nach nicht der Fall ist, aber nehmen wir für diese Erklärung an :-)). Ihres Interesses, dann kann Ihr Problem allein mit der Standardbibliothek (C++11 und neuer) vollständig gelöst werden.
Die TL;DR-Version:
#include <locale>
#include <codecvt>
#include <string>
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> 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 zeigen alle das gleiche Beispiel. Es gibt nur viele für Redundanz …)
Hinweis (alt):
Wie in den Kommentaren hervorgehoben und in https://stackoverflow.com/a/17106065/6345 erläutert, gibt es Fälle, in denen die Verwendung der Standardbibliothek zum Konvertieren zwischen UTF-8 und UTF-16 zu unerwarteten Unterschieden in den Ergebnissen auf verschiedenen Plattformen führen kann . Berücksichtigen Sie für eine bessere Konvertierung std::codecvt_utf8
wie auf beschrieben http://en.cppreference.com/w/cpp/locale/codecvt_utf8
Hinweis (neu):
Seit der codecvt
Header in C++17 veraltet ist, wurden einige Bedenken hinsichtlich der in dieser Antwort vorgestellten Lösung geäußert. Das C++-Standardkomitee fügte jedoch eine wichtige Aussage hinzu http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html Sprichwort
diese Bibliothekskomponente sollte zusammen mit Seite in Anhang D zurückgezogen werden, bis ein geeigneter Ersatz standardisiert ist.
Also in absehbarer Zeit die codecvt
Die Lösung in dieser Antwort ist sicher und tragbar.
Überprüfen Sie, mit welcher Codierung Sie VS-Dateien speichern
– Johann Gerell
8. November 2013 um 10:39 Uhr
Beachten Sie, dass dies nur C++ 11 ist!
– bk138
15. Januar 2014 um 13:58 Uhr
Bitte beachte, dass <codecvt>
ist seit C++17 veraltet.
– Tambre
9. April 2017 um 11:01 Uhr
@tambre – danke für den Hinweis, ich habe die hinzugefügt Hinweis (neu) Absatz, um darauf einzugehen.
– Johann Gerell
28. Juli 2017 um 7:32 Uhr
Wenn ich der alleinige und allmächtige Herrscher dieser Welt wäre, würde ich dekretieren, dass UTF16 geächtet ist und nur UTF8 und UTF32 legal und ohne die Gefahr strenger Strafen nutzbar sind. 😉 Ich meine ernsthaft – wozu ist UTF16 gut, wenn es immer noch Multi-Code-Point ist?! All dieser Ärger mit Konvertierungen hat die Hauptursache, dass UTF16 fehlerhaft ist, IMHO.
– BitTickler
7. März 2020 um 20:23 Uhr
int StringToWString(std::wstring &ws, const std::string &s)
{
std::wstring wsTmp(s.begin(), s.end());
ws = wsTmp;
return 0;
}
Dies funktioniert nur, wenn alle Zeichen Single Byte sind, also ASCII oder ISO-8859-1. Alles Multibyte wird kläglich scheitern, einschließlich UTF-8. Die Frage enthält eindeutig Multibyte-Zeichen.
– Markieren Sie Lösegeld
3. September 2013 um 16:22 Uhr
Diese Antwort ist eindeutig unzureichend und kopiert nur schmale Zeichen unverändert in breite Zeichen. Siehe die anderen Antworten, insbesondere die von Johann Gerell, um zu erfahren, wie man richtig von einer Multibyte- oder utf8-codierten Zeichenfolge zu einer utf16-wstring wechselt.
– DLRdave
13. Oktober 2013 um 11:29 Uhr
Diese Antwort ist gefährlich und wird wahrscheinlich auf Nicht-ASCII-Systemen brechen. dh ein arabischer Dateiname wird durch diesen Hack verstümmelt.
– Stefan
18. April 2014 um 19:50 Uhr
Diese Antwort ist nützlich, wenn Sie die Nuancen des Fragetexts ignorieren und sich auf den Fragentitel konzentrieren, der mich von Google hierher gebracht hat. So lautet der Titel der Frage äußerst irreführend und sollten geändert werden, um die wahre Frage widerzuspiegeln, die gestellt wird
– Anne Quinn
17. Dezember 2015 um 7:37 Uhr
Dies funktioniert nur für 7-Bit-ASCII-Zeichen. Für latin1 funktioniert es nur, wenn char als unsigned konfiguriert ist. Wenn der Typ char signiert ist (was meistens der Fall ist), führen Zeichen > 127 zu falschen Ergebnissen.
– huyc
16. Mai 2016 um 18:32 Uhr
Kartoffelklatsche
Ihre Frage ist unterspezifiziert. Genau genommen handelt es sich bei diesem Beispiel um einen Syntaxfehler. Aber, mbstowcs
ist wahrscheinlich das, wonach Sie suchen.
Es ist eine C-Bibliotheksfunktion und arbeitet mit Puffern, aber hier ist eine einfach zu verwendende Redewendung, mit freundlicher Genehmigung von Mooing Duck:
std::wstring ws(s.size(), L' '); // Overestimate number of code points.
ws.resize(::mbstowcs_s(&ws[0], ws.size(), s.c_str(), s.size())); // Shrink to fit.
string s = “おはよう”; wchar_t* buf = neues wchar_t[ s.size() ]; size_t num_chars = mbstowcs( buf, s.c_str(), s.size() ); wstring ws( buf, num_chars ); // ws = verzerrt
– Samir
4. April 2010 um 8:23 Uhr
@Samir: Sie müssen sicherstellen, dass die Laufzeitcodierung mit der Kompilierzeitcodierung übereinstimmt. Möglicherweise müssen Sie setlocale
oder Compiler-Flags anpassen. Ich weiß es nicht, weil ich kein Windows verwende, aber deshalb ist es kein gemeinsames Feature. Betrachten Sie die andere Antwort, wenn möglich.
– Kartoffelklatsche
4. April 2010 um 9:30 Uhr
std::string ws(s.size()); ws.resize(mbstowcs(&ws[0], s.c_str(), s.size());
RAII-FTW
– Muhende Ente
3. September 2013 um 17:01 Uhr
@WaffleSouffle Das ist veraltet. Seit 2011 sind zusammenhängende Implementierungen erforderlich, und Implementierungen haben solche Tricks schon lange vorher aufgegeben.
– Kartoffelklatsche
22. September 2014 um 23:53 Uhr
und einige Umgebungen wie mingw haben immer noch nicht den Codecvt-Header, so dass einige der “besseren” Lösungen von früher nicht funktionieren, was bedeutet, dass dieses Problem auch im Dezember 2014 noch keine guten Lösungen in mingw hat
– Brian Jack
11. Dezember 2014 um 19:54 Uhr
lmiguelmh
Wenn Sie verwenden Fenster/Visuelles Studio und müssen eine Zeichenfolge in wstring konvertieren, die Sie verwenden könnten:
#include <AtlBase.h>
#include <atlconv.h>
...
string s = "some string";
CA2W ca2w(s.c_str());
wstring w = ca2w;
printf("%s = %ls", s.c_str(), w.c_str());
Dasselbe Verfahren zum Konvertieren einer wstring in eine Zeichenfolge (manchmal müssen Sie eine angeben Codepage):
#include <AtlBase.h>
#include <atlconv.h>
...
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 a angeben Codepage und sogar UTF8 (das ist ziemlich nett, wenn man damit arbeitet JNI/Java). EIN Standard Die Methode zum Konvertieren eines std::wstring in utf8 std::string wird in dieser Antwort gezeigt.
//
// using ATL
CA2W ca2w(str, CP_UTF8);
//
// or the standard way taken from the answer above
#include <codecvt>
#include <string>
// convert UTF-8 string to wstring
std::wstring utf8_to_wstring (const std::string& str) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return myconv.from_bytes(str);
}
// convert wstring to UTF-8 string
std::string wstring_to_utf8 (const std::wstring& str) {
std::wstring_convert<std::codecvt_utf8<wchar_t>> myconv;
return myconv.to_bytes(str);
}
Wenn Sie mehr darüber wissen möchten Codeseiten es gibt einen interessanten Artikel über Joel on Software: Das absolute Minimum, das jeder Softwareentwickler unbedingt und unbedingt über Unicode und Zeichensätze wissen muss.
Diese CA2W-Makros (Convert Ansi to Wide=unicode) sind Teil von ATL- und MFC-StringkonvertierungsmakrosProben enthalten.
Manchmal müssen Sie die Sicherheitswarnung Nr. 4995 deaktivieren, ich kenne keine andere Problemumgehung (bei mir ist es passiert, als ich in VS2012 für WindowsXp kompiliert habe).
#pragma warning(push)
#pragma warning(disable: 4995)
#include <AtlBase.h>
#include <atlconv.h>
#pragma warning(pop)
Bearbeiten:
Nun, laut Dieser Beitrag Der Artikel von Joel scheint zu sein: “Während er unterhaltsam ist, geht er ziemlich leicht auf tatsächliche technische Details ein”. Artikel: Was jeder Programmierer unbedingt und unbedingt über Kodierung und Zeichensätze wissen muss, um mit Text zu arbeiten.
Nur Windows-API, Implementierung vor C++11, falls jemand sie braucht:
#include <stdexcept>
#include <vector>
#include <windows.h>
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<wchar_t> 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);
}
Sie können es optimieren. Es ist nicht erforderlich, die Zeichenfolge mit a doppelt zu kopieren vector
. Reservieren Sie einfach die Zeichen in der Zeichenfolge, indem Sie dies tun wstring strW(charsNeeded + 1);
und dann als Puffer für die Konvertierung verwenden: &strW[0]
. Stellen Sie abschließend sicher, dass die letzte Null nach der Konvertierung vorhanden ist, indem Sie dies tun strW[charsNeeded] = 0;
– c00000fd
6. Februar 2017 um 3:35 Uhr
@ c00000fd, soweit ich weiß, muss der interne Puffer std :: basic_string erst seit dem C ++ 11-Standard kontinuierlich sein. Mein Code ist vor C ++ 11, wie oben im Beitrag angegeben. Daher ist &strW[0] Code wäre nicht standardkonform und könnte berechtigterweise zur Laufzeit abstürzen.
– Alex Che
6. Februar 2017 um 7:03 Uhr
Hier ist ein Weg zum Kombinieren string
, wstring
und gemischte Zeichenfolgenkonstanten zu wstring
. Verwenden Sie die wstringstream
Klasse.
Dies funktioniert NICHT bei Multi-Byte-Zeichenkodierungen. Dies ist nur eine dumme Art, die Typsicherheit wegzuwerfen und 7-Bit-Zeichen von std::string in die unteren 7 Bits jedes Zeichens von std:wstring zu erweitern. Dies ist nur nützlich, wenn Sie 7-Bit-ASCII-Zeichenfolgen haben und eine API aufrufen müssen, die breite Zeichenfolgen erfordert.
#include <sstream>
std::string narrow = "narrow";
std::wstring wide = L"wide";
std::wstringstream cls;
cls << " abc " << narrow.c_str() << L" def " << wide.c_str();
std::wstring total= cls.str();
Sie können es optimieren. Es ist nicht erforderlich, die Zeichenfolge mit a doppelt zu kopieren vector
. Reservieren Sie einfach die Zeichen in der Zeichenfolge, indem Sie dies tun wstring strW(charsNeeded + 1);
und dann als Puffer für die Konvertierung verwenden: &strW[0]
. Stellen Sie abschließend sicher, dass die letzte Null nach der Konvertierung vorhanden ist, indem Sie dies tun strW[charsNeeded] = 0;
– c00000fd
6. Februar 2017 um 3:35 Uhr
@ c00000fd, soweit ich weiß, muss der interne Puffer std :: basic_string erst seit dem C ++ 11-Standard kontinuierlich sein. Mein Code ist vor C ++ 11, wie oben im Beitrag angegeben. Daher ist &strW[0] Code wäre nicht standardkonform und könnte berechtigterweise zur Laufzeit abstürzen.
– Alex Che
6. Februar 2017 um 7:03 Uhr
rubenvb
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 dies nur gut funktioniert, wenn die zu konvertierende Zeichenfolge nur ASCII-Zeichen enthält.
Denn dies funktioniert nur, wenn die Codierung Windows-1252 ist, die nicht einmal die Buchstaben in der Frage enthalten kann.
– Muhende Ente
4. September 2013 um 16:54 Uhr
Dies ist die am wenigsten fehleranfällige Methode, wenn Sie wissen, dass Sie mit ASCII arbeiten. Dies ist ein prominenter Anwendungsfall beim Portieren von Apps auf neuere APIs.
– Sid Saraswati
25. Februar 2014 um 19:45 Uhr
Das ist nicht der Weg. Wenn Sie Visual Studio verwenden, sollten Sie verwenden atlconv.h
. Überprüfen Sie die anderen Antworten.
– lmiguelmh
5. November 2014 um 22:50 Uhr
Ich denke nicht
strings
akzeptiert >8-Bit-Zeichen. Ist es bereits in UTF-8 kodiert?– kennytm
4. April 2010 um 7:36 Uhr
Was ist Ihre Systemcodierung, die es machen würde
"おはよう"
eine systemcodierte Zeichenfolge?– sbi
4. April 2010 um 7:42 Uhr
Ich glaube, MSVC wird das akzeptieren und es zu einer Multibyte-Codierung machen, vielleicht UTF-8.
– Kartoffelklatsche
4. April 2010 um 7:47 Uhr
@Potatoswatter: MSVC verwendet UTF-8 standardmäßig für NICHTS. Wenn Sie diese Zeichen eingeben, werden Sie gefragt, in welche Codierung die Datei konvertiert werden soll, und verwenden standardmäßig die Codepage 1252.
– Muhende Ente
3. September 2013 um 16:58 Uhr
@Samir: wichtiger ist, was die Codierung der ist Datei? Können Sie diese Zeichenfolge an den Anfang der Datei verschieben und einen Hexdump dieses Teils anzeigen? Daran können wir es wahrscheinlich erkennen.
– Muhende Ente
3. September 2013 um 16:59 Uhr