Konvertieren von std :: string in LPCWSTR in C ++ (Unicode)


Antworten:


133

Vielen Dank für den Link zum MSDN-Artikel. Genau das habe ich gesucht.

std::wstring s2ws(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;
}

std::wstring stemp = s2ws(myString);
LPCWSTR result = stemp.c_str();

4
(Diese Frage wurde zufällig durchsucht. Es ist lange her, seit ich C ++ gemacht habe.) Die Standardbibliothek hat also keine std :: string -> std :: wstring-Konvertierung? Das scheint komisch; Gibt es einen guten Grund?
Domenic

5
Wenn Sie std :: vector <wchar_t> verwenden, um Speicher für buf zu erstellen, wird Ihr temporärer Puffer freigegeben, wenn irgendetwas eine Ausnahme auslöst.
Jason Harrison

81
Grund # 233, warum C ++ mich verdammt nervt..10 Codezeilen für eine einfache String-Konvertierung = /
b1nary.atr0phy

2
Oder sagen Sie einfach wstring ws (s.begin (), s.end ()) ...?
CJBrew

3
@CJBrew: Für jedes Problem gibt es eine Lösung, die sauber, elegant und falsch ist. Ihre basiert auf der Annahme, dass Ihre Eingabe nur ASCII-Zeichen ( nicht ANSI-Zeichen) enthält.
Unsichtbarer

121

Die Lösung ist tatsächlich viel einfacher als alle anderen Vorschläge:

std::wstring stemp = std::wstring(s.begin(), s.end());
LPCWSTR sw = stemp.c_str();

Das Beste ist, dass es plattformunabhängig ist. h2h :)


2
Sorry Benny, aber das funktioniert bei mir nicht, Torans eigene Lösung scheint aber gut zu funktionieren (aber ... blöd!).
Iain Collins

32
Dies funktioniert nur, wenn alle Zeichen Einzelbyte sind, dh ASCII oder ISO-8859-1 . Alles, was mit mehreren Bytes zu tun hat, schlägt kläglich fehl, einschließlich UTF-8.
Mark Ransom

Ich glaube, Sie können die erste Zeile vereinfachen, um: std :: wstring stemp (s.begin (), s.end ()); Das würde eine mögliche Kopie eliminieren und einfacher aussehen; Beachten Sie, dass der Compiler die Kopie möglicherweise trotzdem entfernt, dies jedoch immer noch einfacher aussieht.
Kit10

13
Herr, was ist mit all den Gegenstimmen? Diese Antwort funktioniert manchmal nur durch Zufall. Zeichenkodierungen werden vollständig ignoriert . Sie können ein schmales Zeichen nicht einfach erweitern und hoffen, dass es sich auf magische Weise in ein breites Zeichen verwandelt, das denselben Codepunkt darstellt. Es ist das moralische Äquivalent von a reinterpret_cast. Dieser Code funktioniert nicht. Verwende nicht. .
Unsichtbarer

2
@nik: Unter Windows wird a charnormalerweise als ANSI codiert. Bei der ANSI-Codierung werden die Werte 128 bis 255 unter Verwendung der aktuell aktiven Codepage interpretiert. Wenn Sie diese Werte in eine wchar_t(UTF-16-Codierung unter Windows) verschieben, wird das gewünschte Ergebnis nicht erzielt . Wenn Sie genau sein möchten, funktioniert dies in genau 50% der Fälle. Unter Berücksichtigung der DBCS-Zeichenkodierung nimmt dieser Prozentsatz weiter ab.
Unsichtbarer

9

Wenn Sie sich in einer ATL / MFC-Umgebung befinden, können Sie das ATL-Konvertierungsmakro verwenden:

#include <atlbase.h>
#include <atlconv.h>

. . .

string myStr("My string");
CA2W unicodeStr(myStr);

Sie können dann unicodeStr als LPCWSTR verwenden. Der Speicher für die Unicode-Zeichenfolge wird auf dem Stapel erstellt und freigegeben. Anschließend wird der Destruktor für unicodeStr ausgeführt.


0

Anstelle eines std :: string können Sie auch einen std :: wstring verwenden.

EDIT: Sorry, das ist nicht erklärender, aber ich muss laufen.

Verwenden Sie std :: wstring :: c_str ()


9
F: "Ich muss von X nach Y konvertieren." - A: "Suchen Sie nach einem Job, bei dem A anstelle von X verwendet wird." Das ist nutzlos.
Unsichtbarer

Kannst du den Wald nicht für alle Bäume sehen? Dies ist nützlich, da es genau das ist, wonach ich gesucht habe
Charlie

-3
string  myMessage="helloworld";
int len;
int slength = (int)myMessage.length() + 1;
len = MultiByteToWideChar(CP_ACP, 0, myMessage.c_str(), slength, 0, 0); 
wchar_t* buf = new wchar_t[len];
MultiByteToWideChar(CP_ACP, 0, myMessage.c_str(), slength, buf, len);
std::wstring r(buf);
 std::wstring stemp = r.C_str();
LPCWSTR result = stemp.c_str();

-3

LPCWSTR lpcwName = std :: wstring (strname.begin (), strname.end ()). C_str ()


2
Diese Lösung wurde bereits vor 9 Jahren von einer der Top-Antworten vorgeschlagen
Nino Filiu

1
Und es war vor 9 Jahren genauso falsch wie heute. Die Kommentare erklären, warum dies nur für einen engen Bereich von Codeeinheiten funktioniert.
Unsichtbarer
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.