Как я могу использовать MultiByteToWideChar? - PullRequest
16 голосов
/ 14 июля 2011

Я хочу преобразовать нормальный string в wstring.Для этого я пытаюсь использовать функцию Windows API MultiByteToWideChar.Но это не работает для меня.

Вот что я сделал:

string x = "This is c++ not java";
wstring Wstring;
MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , x.size() , &Wstring , 0 ); 

Последняя строка выдает ошибку компилятора:

'MultiByteToWideChar' : cannot convert parameter 5 from 'std::wstring *' to 'LPWSTR'

Как мнеисправить эту ошибку?

Кроме того, каким должно быть значение аргумента cchWideChar?0 хорошо?

Ответы [ 4 ]

33 голосов
/ 14 июля 2011

Вы должны вызвать MultiByteToWideChar дважды:

  1. Первый вызов MultiByteToWideChar используется для определения размера буфера, необходимого для широкой строки.Посмотрите на документацию Microsoft ;в нем говорится:

    Если функция завершается успешно и cchWideChar равно 0, возвращаемое значение - требуемый размер в символах для буфера, указанного lpWideCharStr .

    Таким образом, чтобы MultiByteToWideChar дал вам требуемый размер, передайте 0 в качестве значения последнего параметра, cchWideChar.Вы также должны передать NULL как предыдущее, lpWideCharStr.

  2. Получить неконстантный буфер, достаточно большой для размещения широкой строки, используя размер буфера из предыдущегошаг.Передайте этот буфер другому вызову MultiByteToWideChar.И на этот раз последним аргументом должен быть фактический размер буфера, а не 0.

Схематичный пример:

int wchars_num = MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , -1, NULL , 0 );
wchar_t* wstr = new wchar_t[wchars_num];
MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , -1, wstr , wchars_num );
// do whatever with wstr
delete[] wstr;

Также обратите внимание на использование-1 в качестве аргумента cbMultiByte.Это приведет к тому, что полученная строка завершится нулем, что избавит вас от необходимости иметь с ними дело.

1 голос
/ 14 июля 2011

Второй вопрос об этом сегодня утром!

WideCharToMultiByte () и MultiByteToWideChar () - трудная задача. Каждое преобразование требует двух обращений к подпрограммам, и вы должны следить за выделением / освобождением памяти и проверкой правильности завершения строк. Вам нужна обертка!

У меня есть удобная оболочка C ++ в моем блоге, здесь , которую вы можете использовать.

Вот другой вопрос этим утром

0 голосов
/ 27 июня 2017

Вы можете попробовать это решение ниже. Я протестировал, он работает, обнаруживает специальные символы (пример: º ç á á) и работает в Windows XP, Windows 2000 с SP4 и более поздних версиях, Windows 7, 8, 8.1 и 10. Используя std::wstring вместо new wchar_t / delete, мы уменьшаем проблемы с утечкой ресурсов, переполнением буфера и поврежденной кучей.

dwFlags было установлено на MB_ERR_INVALID_CHARS для работы в Windows 2000 с пакетом обновления 4 и более поздних версий, Windows XP. Если этот флаг не установлен, функция автоматически отбрасывает недопустимые кодовые точки.

std::wstring ConvertStringToWstring(const std::string &str)
{
    if (str.empty())
    {
        return std::wstring();
    }
    int num_chars = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), NULL, 0);
    std::wstring wstrTo;
    if (num_chars)
    {
        wstrTo.resize(num_chars);
        if (MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS, str.c_str(), str.length(), &wstrTo[0], num_chars))
        {
            return wstrTo;
        }
    }
    return std::wstring();
}
0 голосов
/ 14 июля 2011

Функция не может взять указатель на строку C ++. Он будет ожидать указатель на буфер широких символов достаточного размера - вы должны выделить этот буфер самостоятельно.

string x = "This is c++ not java";
wstring Wstring;
Wstring.resize(x.size());
int c =  MultiByteToWideChar( CP_UTF8 , 0 , x.c_str() , x.size() , &Wstring[0], 0 ); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...