Конвертировать char * в LPWSTR - PullRequest
33 голосов
/ 28 июля 2011

Я пытаюсь преобразовать программу для многобайтового символа в Unicode.

Я прошел программу и предварял строковые литералы L, поэтому они выглядят как L"string".

Это сработало, но теперь у меня осталась строка в стиле C, которая не будет соответствовать. Я пробовал L и помещал его в TEXT(), но L добавляется к имени переменной, а не к строке, если я использую TEXT().

Я пытался сделать его TCHAR, но потом жалуется, что не может преобразовать TCHAR в char *.

Какие варианты у меня остались?

Я знаю, что C и C ++ разные. Это старая внутренняя библиотека C, которая используется в проектах C ++ уже несколько лет.

Ответы [ 5 ]

40 голосов
/ 28 июля 2011

Функция std::mbstowcs - это то, что вы ищете:

 char text[] = "something";
 wchar_t wtext[20];
 mbstowcs(wtext, text, strlen(text)+1);//Plus null
 LPWSTR ptr = wtext;

для string с,

 string text = "something";
 wchar_t wtext[20];
 mbstowcs(wtext, text.c_str(), text.length());//includes null
 LPWSTR ptr = wtext;

-> ED:Префикс «L» работает только со строковыми литералами, а не с переменными.<- </p>

12 голосов
/ 28 июля 2011

Чистый способ использования mbstowcs - вызвать его дважды, чтобы узнать длину результата:

  const char * cs = <your input char*>
  size_t wn = mbsrtowcs(NULL, &cs, 0, NULL);

  // error if wn == size_t(-1)

  wchar_t * buf = new wchar_t[wn + 1]();  // value-initialize to 0 (see below)

  wn = mbsrtowcs(buf, &cs, wn + 1, NULL);

  // error if wn == size_t(-1)

  assert(cs == NULL); // successful conversion

  // result now in buf, return e.g. as std::wstring

  delete[] buf;

Не забудьте позвонить setlocale(LC_CTYPE, ""); в начале вашей программы!

Преимущество перед Windows MultiByteToWideChar состоит в том, что это полностью стандартный C, хотя в Windows вы все равно можете предпочесть функцию Windows API.

Я обычно заключаю этот метод вместе с противоположным в две функции преобразования string -> wstring и wstring -> string. Если вы также добавите тривиальные перегрузки string -> string и wstring -> wstring, вы можете легко написать код, который компилируется с typedef Winapi TCHAR в любой настройке.

[ Edit: ] Я добавил нулевую инициализацию к buf, на случай, если вы планируете использовать массив C напрямую. Я обычно возвращал бы результат как std::wstring(buf, wn), но остерегайтесь, если вы планируете использовать массивы с нулевым символом в конце в стиле C. [/]

В многопоточной среде вы должны передать функцию локального преобразования потока в функцию в качестве ее последнего (в настоящее время невидимого) параметра.

Вот моя маленькая напыщенная речь по этой теме.

4 голосов
/ 28 июля 2011

Эта версия, используя функцию Windows API MultiByteToWideChar(), обрабатывает выделение памяти для произвольно длинных строк ввода.

int lenA = lstrlenA(input);
int lenW = ::MultiByteToWideChar(CP_ACP, 0, input, lenA, NULL, 0);
if (lenW>0)
{
    output = new wchar_t[lenW];
    ::MultiByteToWideChar(CP_ACP, 0, input, lenA, output, lenW);
} 
1 голос
/ 28 июля 2011

Вы можете использовать CString, CStringA, CStringW для автоматического преобразования и преобразования между этими типами.Кроме того, вы также можете использовать CStrBuf, CStrBufA, CStrBufW, чтобы получить строки, модифицируемые шаблоном RAII

0 голосов
/ 23 апреля 2019

Я использую следующее в VC ++, и оно работает для меня как шарм.

CA2CT(charText)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...