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

Lesezeit: 10 Minuten

C String oder char in wstring oder wchar t konvertieren
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.

  • 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

1647091211 397 C String oder char in wstring oder wchar t konvertieren
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

C String oder char in wstring oder wchar t konvertieren
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

C String oder char in wstring oder wchar t konvertieren
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

1647091212 204 C String oder char in wstring oder wchar t konvertieren
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

993710cookie-checkC++ String (oder char*) in wstring (oder wchar_t*) konvertieren

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy