Як конвертувати std :: string в LPCWSTR в C ++ (Unicode)


Відповіді:


134

Дякуємо за посилання на статтю MSDN. Це саме те, що я шукав.

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
(Знайшов це питання, переглядаючи випадковим чином; пройшов давно C ++.) Отже, у стандартній бібліотеці немає std :: string -> std :: wstring конверсії? Це здається дивним; чи є вагомі причини?
Доменіч

5
Якщо ви використовуєте std :: vector <wchar_t> для створення сховища для buf, тоді, якщо щось буде винятком, ваш тимчасовий буфер буде звільнений.
Джейсон Харрісон

81
причина # 233 про те, чому c ++ дратує пекло мене ... 10 рядків коду для простого перетворення рядка = /
b1nary.atr0phy

2
Або просто сказати wstring ws (s.begin (), s.end ()) ...?
CJBrew

3
@CJBrew: Для кожної проблеми є рішення, це чисто, елегантно і неправильно. Ваше базується на припущенні, що ваш вхід містить лише символи ASCII ( не ANSI).
Неочікуваний

121

Рішення насправді набагато простіше, ніж будь-яка інша пропозиція:

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

Найкраще, що це платформа незалежна. h2h :)


2
Вибачте Бенні, але це не працює для мене, власне рішення Торана, здається, працює добре (хоча ... але!!).
Ієн Коллінз

32
Це працює лише в тому випадку, якщо всі символи є однобайтовими, тобто ASCII або ISO-8859-1 . Все багатобайтове вийде з ладу, включаючи UTF-8.
Марк Рансом

Я вважаю, що ви можете спростити перший рядок до: std :: wstring stemp (s.begin (), s.end ()); Це дозволило б усунути можливу копію і виглядати простіше; зауважте, що компілятор може усунути копію так чи інакше, але це все ж більш простий вигляд.
Kit10

13
Господи, що з усіма новинами? Ця відповідь іноді працює лише за збігом обставин. Він повністю ігнорує кодування символів . Ви не можете просто розширити вузький символ і сподіватися, що він магічним чином перетвориться на широкий символ, що представляє ту саму кодову точку. Це моральний еквівалент а reinterpret_cast. Цей код не працює. Не використовувати. .
Неочікуваний

2
@nik: У Windows, a charзазвичай кодується як ANSI. При кодуванні ANSI значення 128 - 255 інтерпретуються за допомогою поточно активної сторінки коду. Переведення цих значень у wchar_t(кодування UTF-16 в Windows) не призведе до бажаного результату. Якщо ви хочете бути точними, це спрацьовує в рівно 50% випадків. Враховуючи кодування символів DBCS, цей відсоток ще більше зменшується.
Неочікуваний

9

Якщо ви перебуваєте в середовищі ATL / MFC, ви можете використовувати макрос перетворення ATL:

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

. . .

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

Потім ви можете використовувати unicodeStr як LPCWSTR. Пам'ять для рядка unicode створюється на стеку і вивільняється, після чого виконується деструктор для unicodeStr.


-1

Замість використання std :: string ви можете використовувати std :: wstring.

EDIT: Вибачте, це не більш пояснювально, але я повинен бігти.

Використовуйте std :: wstring :: c_str ()


9
Питання: "Мені потрібно перетворити з X на Y." - A: "Шукайте роботу, де вони використовують A замість X." Це марно.
Неочікуваний

Не можете побачити ліс для всіх дерев? Це корисно, оскільки саме це я шукав
Чарлі,

-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
Це рішення вже було запропоновано 9 років тому однією з найкращих відповідей
Ніно

1
І це було неправильно 9 років тому стільки, скільки це неправильно сьогодні. У коментарях пояснюється, чому це працює лише для вузького кола кодових одиниць.
Неочікуваний
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.