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

115

Szukam metody lub fragmentu kodu do konwersji std :: string na LPCWSTR

Toran Billups
źródło
1
Jak postępujemy odwrotnie?
Sohaib,
Pochodzę z Google, próbując zrobić coś przeciwnego. Nie znalazłeś metody?
Tomáš Zato - Przywróć Monikę

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();
Toran Billups
źródło
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 :)

Benny Hilfiger
źródło
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.

17 z 26
źródło
-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 ()

Ed S.
źródło
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();
Milind Morey
źródło
-3

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

Milind Morey
źródło
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