Jak przekonwertować std :: string na LPCWSTR w C ++ (Unicode)


Odpowiedzi:


134

Dzięki za link do artykułu MSDN. To jest dokładnie to, czego szukałem.

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
(Znalazłem to pytanie, przeglądając losowo; minęło dużo czasu, odkąd zrobiłem C ++.) Więc standardowa biblioteka nie ma konwersji std :: string -> std :: wstring? To wydaje się dziwne; czy jest dobry powód?
Domenic

5
Jeśli użyjesz std :: vector <wchar_t> do utworzenia pamięci dla bufora, to jeśli cokolwiek zgłosi wyjątek, twój tymczasowy bufor zostanie zwolniony.
Jason Harrison,

81
powód # 233 dlaczego c ++ denerwuje mnie do diabła ... 10 linii kodu do prostej konwersji ciągów = /
b1nary.atr0phy

2
Lub po prostu powiedz wstring ws (s.begin (), s.end ()) ...?
CJBrew

3
@CJBrew: Dla każdego problemu istnieje rozwiązanie, które jest czyste, eleganckie i błędne. Twój jest oparty na założeniu, że twoje dane wejściowe przechodzą tylko znaki ASCII ( nie ANSI).
Niespodziewane

122

Rozwiązanie jest w rzeczywistości dużo łatwiejsze niż jakiekolwiek inne sugestie:

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

A co najważniejsze, jest niezależny od platformy. h2h :)


2
Przepraszam Benny, ale to nie działa dla mnie, rozwiązanie Torana wydaje się jednak działać dobrze (ale… blegh!).
Iain Collins

32
Działa to tylko wtedy, gdy wszystkie znaki są jednobajtowe, np. ASCII lub ISO-8859-1 . Wszystko, co wielobajtowe, zakończy się niepowodzeniem, w tym UTF-8.
Mark Ransom,

Wierzę, że możesz uprościć pierwszą linię do: std :: wstring stemp (s.begin (), s.end ()); To wyeliminowałoby możliwą kopię i wyglądałoby na prostsze; Zwróć uwagę, że kompilator i tak może usunąć kopię, ale nadal jest to prostszy wygląd.
Kit10

13
Panie, o co chodzi z tymi wszystkimi pozytywnymi opiniami? Ta odpowiedź działa czasami tylko przez przypadek. Całkowicie ignoruje kodowanie znaków . Nie możesz po prostu poszerzyć wąskiej postaci i mieć nadzieję, że magicznie zmieni się ona w szeroką postać reprezentującą ten sam punkt kodowy. Jest to moralny odpowiednik reinterpret_cast. Ten kod nie działa. Nie używać. .
Niespodziewane

2
@nik: W systemie Windows a charjest zwykle kodowane jako ANSI. W przypadku kodowania ANSI wartości od 128 do 255 są interpretowane przy użyciu aktualnie aktywnej strony kodowej. Przeniesienie tych wartości do wchar_t(kodowanie UTF-16 w systemie Windows) nie przyniesie pożądanego rezultatu. Jeśli chcesz być precyzyjny, działa to dokładnie w 50% przypadków. Biorąc pod uwagę kodowanie znaków DBCS, ten procent dalej spada.
Niespodziewane

9

Jeśli pracujesz w środowisku ATL / MFC, możesz użyć makra konwersji ATL:

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

. . .

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

Następnie możesz użyć unicodeStr jako LPCWSTR. Pamięć dla ciągu znaków Unicode jest tworzona na stosie i zwalniana, a następnie wykonuje się destruktor dla unicodeStr.


-1

Zamiast używać std :: string, możesz użyć std :: wstring.

EDYCJA: Przepraszam, to nie jest bardziej wyjaśniające, ale muszę biec.

Użyj std :: wstring :: c_str ()


9
P: „Muszę przekonwertować z X na Y”. - O: „Poszukaj pracy, w której używają litery A zamiast X”. To jest bezużyteczne.
Niespodziewane

Nie widzę lasu dla wszystkich drzew? Jest to przydatne, ponieważ jest to dokładnie to, czego szukałem
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
To rozwiązanie zostało zaproponowane już 9 lat temu przez jedną z najpopularniejszych odpowiedzi
Nino Filiu

1
I było źle 9 lat temu, tak samo jak jest źle dzisiaj. Komentarze wyjaśniają, dlaczego działa to tylko dla wąskiego zakresu jednostek kodu.
Niespodziewane
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.