2011-07-28 9 views
26

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

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

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

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

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

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

+1

Основная причина, по которой кто-то мог бы сделать downvote больше, imho, отсутствие исходного кода в вашем вопросе. Изображение стоит тысячи слов, а также часть кода. Даже тривиальный. – ereOn

+0

Вы можете определенно написать код, который работает с 'TCHAR' независимо от того, какой параметр компилятора, вам просто нужно создать нужную инфраструктуру. В C++ перегрузка делает весь тяжелый подъем для вас. –

+0

Связано ли это с C или C++? –

ответ

30

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

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

-> ED: Приставка "L" работает только на строковых литералов, а не переменных. < -

+1

, который устарел, вы должны использовать 'mbstowcs_s () ' – Olipro

+1

@Olipro: Это« устарело »только в мире Windows. ОП не указал, на какой платформе он нацелился. – ereOn

+3

довольно очевидно, что платформа - это Windows, но если вы думаете иначе, продолжайте и докажите, что я ошибаюсь. – Olipro

11

Чистый способ использования 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, вы можете легко написать код, который скомпилирован с Winapi TCHAR typedef в любой настройке.

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

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

Здесь находится small rant по этой теме.

+1

+1 для отображения того, как вызвать функцию дважды, чтобы получить длину выходного буфера –

+0

Приветствия. В конфиденциальности моих собственных мыслей я фактически использую массив переменной длины для 'buf', но я хотел избежать этого в свете SO-проверки :-) –

+0

Обновление: в настоящее время я бы искал [' codecvt'] (http://en.cppreference.com/w/cpp/locale/codecvt), который обертывает 'mbsrtowcs' /' wcsrtombs'. –

4

Эта версия, используя функцию 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); 
} 
+3

Утечка памяти, утечка памяти :-) –

+0

@ Kerrek В интересах краткости я пропустил код, который называет 'free' ;-) –

+1

Я бы предпочел, чтобы вы оставили его как есть, чем называть' free() '! Это определенно случай для знаменитого выражения 'delete []' :-) –

1

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

+0

Обратите внимание, что они специфичны для ATL/MFC. – JBES

+0

@ JBES, Да. Я ответил 6 лет назад, когда ATL/MFC в основном использовался. Теперь даже язык C++ имеет функции библиотеки для конверсий. – Ajay

Смежные вопросы