Die Frage ist, wie man wstring in string konvertiert.
Ich habe nächstes Beispiel:
#include <string>
#include <iostream>
int main()
{
std::wstring ws = L"Hello";
std::string s( ws.begin(), ws.end() );
//std::cout <<"std::string = "<<s<<std::endl;
std::wcout<<"std::wstring = "<<ws<<std::endl;
std::cout <<"std::string = "<<s<<std::endl;
}
Die Ausgabe mit auskommentierter Zeile lautet:
std::string = Hello
std::wstring = Hello
std::string = Hello
aber ohne ist nur:
std::wstring = Hello
Stimmt etwas im Beispiel nicht? Kann ich die Konvertierung wie oben durchführen?
BEARBEITEN
Neues Beispiel (unter Berücksichtigung einiger Antworten) ist
#include <string>
#include <iostream>
#include <sstream>
#include <locale>
int main()
{
setlocale(LC_CTYPE, "");
const std::wstring ws = L"Hello";
const std::string s( ws.begin(), ws.end() );
std::cout<<"std::string = "<<s<<std::endl;
std::wcout<<"std::wstring = "<<ws<<std::endl;
std::stringstream ss;
ss << ws.c_str();
std::cout<<"std::stringstream = "<<ss.str()<<std::endl;
}
Die Ausgabe ist:
std::string = Hello
std::wstring = Hello
std::stringstream = 0x860283c
Daher kann der Stringstream nicht zum Konvertieren von wstring in string verwendet werden.
std::wstring
überhaupt verwenden? stackoverflow.com/questions/1049947/…Antworten:
Hier ist eine ausgearbeitete Lösung, die auf den anderen Vorschlägen basiert:
Dies funktioniert normalerweise unter Linux, führt jedoch unter Windows zu Problemen.
quelle
std::setlocale(LC_ALL, "");
wirklich gebraucht?std::wcout.imbue(locale)
sollte auch die Arbeit erledigen, und es hat den Vorteil, dass es keinen globalen Zustand ändert.std::wstring_convert
von C ++ 11 schließt einen Großteil dieses Rauschens ab.*** glibc detected *** test: malloc(): smallbin double linked list corrupted: 0x000000000180ea30 ***
Linux 64-Bit (gcc 4.7.3). Hat das noch jemand erlebt?Wie Cubbi in einem der Kommentare hervorhob, bietet
std::wstring_convert
(C ++ 11) eine saubere, einfache Lösung (Sie müssen#include
<locale>
und<codecvt>
):Ich habe eine Kombination von verwendet
wcstombs
langwieriger Zuweisung / Freigabe von Speicher verwendet, bevor ich darauf gestoßen bin.http://en.cppreference.com/w/cpp/locale/wstring_convert
Update (28.11.2013)
Ein Liner kann so angegeben werden (Danke Guss für Ihren Kommentar):
Wrapper-Funktionen können wie folgt angegeben werden: (Vielen Dank, ArmanSchwarz, für Ihren Kommentar)
Hinweis: Es gibt einige Kontroversen darüber, ob
string
/wstring
als Funktionen oder als Literale an Funktionen übergeben werden soll (aufgrund von C ++ 11 und Compiler-Updates). Ich überlasse die Entscheidung der Person, die sie implementiert, aber es lohnt sich zu wissen.Hinweis: Ich benutze
std::codecvt_utf8
den obigen Code, aber wenn Sie UTF-8 nicht verwenden, müssen Sie dies in die entsprechende Codierung ändern, die Sie verwenden:http://en.cppreference.com/w/cpp/header/codecvt
quelle
std::wstring str = std::wstring_convert<std::codecvt_utf<wchar_t>>().from_bytes("some string");
Lösung von: http://forums.devshed.com/c-programming-42/wstring-to-string-444006.html
Beachten Sie, dass hier überhaupt keine Zeichensatzkonvertierung stattfindet. Was dies bedeutet ist einfach zuweisen jede iterativ
wchar_t
zu einemchar
- eine Kürzen Umwandlung. Es verwendet den std :: string c'tor :Wie in den Kommentaren angegeben:
- -
Und beachten Sie, dass Codepunkte im Bereich
0x80 - 0x9F
in Win1252 wird nicht funktionieren. Dazu gehört€
,œ
,ž
,Ÿ
, ...quelle
Wenn Sie wissen, dass Ihre Zeichenfolge konvertierbar ist, tun Sie einfach Folgendes, anstatt das Gebietsschema und all diese ausgefallenen Dinge einzuschließen:
Live Beispiel hier
quelle
Ich glaube, der offizielle Weg besteht immer noch darin, durch
codecvt
Facetten zu gehen (Sie benötigen eine länderspezifische Übersetzung), wie inoder so ähnlich, ich habe keinen Arbeitscode herumliegen. Aber ich bin mir nicht sicher, wie viele Leute heutzutage diese Maschinerie benutzen und wie viele einfach nach Zeigern auf das Gedächtnis fragen und die Intensivstation oder eine andere Bibliothek die blutigen Details behandeln lassen.
quelle
Es gibt zwei Probleme mit dem Code:
Die Konvertierung in
const std::string s( ws.begin(), ws.end() );
ist nicht erforderlich, um die breiten Zeichen korrekt ihrem schmalen Gegenstück zuzuordnen. Höchstwahrscheinlich wird jedes breite Zeichen nur typisiertchar
.Die Lösung für dieses Problem ist bereits in der Antwort von kem angegeben und beinhaltet die
narrow
Funktion derctype
Facette des Gebietsschemas .Sie schreiben die Ausgabe in beide
std::cout
undstd::wcout
im selben Programm. Beidecout
undwcout
sind demselben Stream (stdout
) zugeordnet, und die Ergebnisse der Verwendung desselben Streams sowohl als byteorientierter Stream (wie es dercout
Fall ist) als auch als breiter orientierter Stream (wie es derwcout
Fall ist) sind nicht definiert.Die beste Option besteht darin, zu vermeiden, dass schmale und breite Ausgaben mit demselben (zugrunde liegenden) Stream gemischt werden. Für
stdout
/cout
/wcout
können Sie versuchen, die Ausrichtung zustdout
ändern, wenn Sie zwischen breitem und schmalem Ausgang wechseln (oder umgekehrt):quelle
Dieser Code hat zwei Formen, um std :: string in std :: wstring und std :: wstring in std :: string zu konvertieren. Wenn Sie #if negiertes WIN32 negieren, erhalten Sie das gleiche Ergebnis.
1. std :: string zu std :: wstring
• MultiByteToWideChar WinAPI
• _mbstowcs_s_l
2. std :: wstring zu std :: string
• WideCharToMultiByte WinAPI
• _wcstombs_s_l
3. Unter Windows müssen Sie Unicode mit WinAPI drucken.
• WriteConsole
4. Im Hauptprogramm.
5. Schließlich benötigen Sie eine leistungsstarke und vollständige Unterstützung für Unicode-Zeichen in der Konsole. Ich empfehle ConEmu und setze es als Standardterminal unter Windows . Sie müssen Visual Studio mit ConEmu verbinden. Denken Sie daran, dass die exe-Datei von Visual Studio lautet devenv.exe lautet
Ergebnis
quelle
Sie können auch die enge Methode der ctype-Facette direkt verwenden:
quelle
Zum Zeitpunkt des Schreibens dieser Antwort würde Sie die erste Google-Suche nach "string string wstring" auf dieser Seite landen. Meine Antwort zeigt, wie man einen String in einen wstring konvertiert, obwohl dies NICHT die eigentliche Frage ist, und ich sollte diese Antwort wahrscheinlich löschen, aber das wird als schlechte Form angesehen. Möglicherweise möchten Sie zu dieser StackOverflow-Antwort springen , die jetzt einen höheren Rang als diese Seite hat.
Hier ist eine Möglichkeit, String-, Wstring- und gemischte String-Konstanten mit Wstring zu kombinieren. Verwenden Sie die Klasse wstringstream.
quelle
Neben der Konvertierung der Typen sollten Sie sich auch des tatsächlichen Formats der Zeichenfolge bewusst sein.
Beim Kompilieren für einen Multi-Byte-Zeichensatz setzt Visual Studio und die Win-API UTF8 voraus (tatsächlich Windows- Codierung, Windows-28591 ).
Beim Kompilieren für den Unicode-Zeichensatz setzt Visual Studio und die Win-API UTF16 voraus.
Sie müssen also auch die Zeichenfolge vom UTF16- in das UTF8-Format konvertieren und nicht nur in std :: string konvertieren.
Dies ist erforderlich, wenn Sie mit Formaten mit mehreren Zeichen wie einigen nicht-lateinischen Sprachen arbeiten.
Die Idee ist zu entscheiden, dass
std::wstring
immer UTF16 repräsentiert .Und repräsentiert
std::string
immer UTF8 .Dies wird vom Compiler nicht erzwungen, sondern ist eher eine gute Richtlinie. Beachten Sie die Zeichenfolgenpräfixe, mit denen ich UTF16 ( L ) und UTF8 ( u8 ) definiere.
Um zwischen den beiden Typen zu konvertieren, sollten Sie Folgendes verwenden: std :: codecvt_utf8_utf16 <wchar_t>
quelle
In meinem Fall muss ich ein Multibyte-Zeichen (MBCS) verwenden und ich möchte std :: string und std :: wstring verwenden. Und kann C ++ 11 nicht verwenden. Also benutze ich mbstowcs und wcstombs.
Ich mache die gleiche Funktion mit new, delete [], aber es ist langsamer als dies.
Dies kann helfen. Gewusst wie: Konvertieren zwischen verschiedenen Zeichenfolgentypen
BEARBEITEN
Wenn die Konvertierung in eine Zeichenfolge und eine Quellzeichenfolge jedoch kein Alphabet und keine Mehrbytezeichenfolge ist, funktioniert dies nicht. Also ändere ich wcstombs in WideCharToMultiByte.
EDIT zu verwenden ‚MultiByteToWideChar‘ anstelle von ‚wcstombs‘
quelle
wcstombs()
.Diese Lösung ist von der Lösung von dk123 inspiriert , verwendet jedoch eine vom Gebietsschema abhängige Codecvt-Facette. Das Ergebnis ist eine in einem Gebietsschema codierte Zeichenfolge anstelle von UTF-8 (wenn es nicht als Gebietsschema festgelegt ist):
Ich habe danach gesucht, aber ich kann es nicht finden. Schließlich stellte ich fest, dass ich die richtige Facette erhalten kann, wenn ich
std::locale
diestd::use_facet()
Funktion mit dem richtigen Typnamen verwende. Hoffe das hilft.quelle
Falls jemand anderes interessiert ist: Ich brauchte eine Klasse, die austauschbar verwendet werden kann, wo immer eine
string
oderwstring
erwartet wird. Die folgende Klasseconvertible_string
, basierend auf dk123-Lösung kann entweder mit einem initialisiert werdenstring
,char const*
,wstring
oderwchar_t const*
und kann durch oder implizit entweder einen umgebautes zugeordnet werdenstring
oderwstring
(so in eine Funktion übergeben werden , die entweder übernehmen).quelle
std::wstring
in der Klasse speichern, alsstd::string
eine Konvertierung zu speichern und durchzuführen,std::wstring
wenn dies erforderlich ist, um eine zu erhaltenstd::wstring
. Weilstd::wstring
ist etwas schneller alsstd::string
und es ist besser kompatibel. Auch es verbraucht mehr Speicher alsstd::string
.quelle
Ich verwende unten, um wstring in string umzuwandeln.
quelle
<string>
) und eine Definition fürWideCharToMultiByte()
- fehlt das ein Wrapperstd::wctomb()
?quelle