utfcpp и Win32 широкий API - PullRequest
       31

utfcpp и Win32 широкий API

3 голосов
/ 25 июля 2010

Хорошо ли / безопасно / можно использовать крошечную библиотеку utfcpp для преобразования всего, что я получаю из широкого Windows API (FindFirstFileW и тому подобное), в действительное представление UTF8 с использованием utf16to8?

Я бы хотел использовать UTF8 для внутреннего использования, но у меня возникли проблемы с получением правильного вывода (через wcout после другого преобразования или простой cout). Нормальные символы ASCII работают, конечно, но они запутались.

Или есть более легкая альтернатива?

Спасибо!

ОБНОВЛЕНИЕ: Благодаря Гансу (ниже), теперь у меня есть простое преобразование UTF8 <-> UTF16 через Windows API. Двухстороннее преобразование работает, но в строке UTF8 из строки UTF16 есть некоторые дополнительные символы, которые позже могут вызвать у меня некоторые проблемы ...). Я поделюсь этим здесь из чистого дружелюбия :)):

// UTF16 -> UTF8 conversion
std::string toUTF8( const std::wstring &input )
{
    // get length
    int length = WideCharToMultiByte( CP_UTF8, NULL,
                                      input.c_str(), input.size(),
                                      NULL, 0,
                                      NULL, NULL );
    if( !(length > 0) )
        return std::string();
    else
    {
        std::string result;
        result.resize( length );

        if( WideCharToMultiByte( CP_UTF8, NULL,
                                 input.c_str(), input.size(),
                                 &result[0], result.size(),
                                 NULL, NULL ) > 0 )
            return result;
        else
            throw std::runtime_error( "Failure to execute toUTF8: conversion failed." );
    }
}
// UTF8 -> UTF16 conversion
std::wstring toUTF16( const std::string &input )
{
    // get length
    int length = MultiByteToWideChar( CP_UTF8, NULL,
                                      input.c_str(), input.size(),
                                      NULL, 0 );
    if( !(length > 0) )
        return std::wstring();
    else
    {
        std::wstring result;
        result.resize( length );

        if( MultiByteToWideChar(CP_UTF8, NULL,
                                input.c_str(), input.size(),
                                &result[0], result.size()) > 0 )
            return result;
        else
            throw std::runtime_error( "Failure to execute toUTF16: conversion failed." );
    }
}

Ответы [ 2 ]

7 голосов
/ 25 июля 2010

В Win32 API уже есть функция для этого, WideCharToMultiByte () с CodePage = CP_UTF8.Избавляет вас от необходимости полагаться на другую библиотеку.

Обычно вы не можете использовать результат с wcout.Его вывод идет на консоль, он использует 8-битную OEM-кодировку по устаревшим причинам.Вы можете изменить кодовую страницу с помощью SetConsoleCP (), 65001 - это кодовая страница для UTF-8 (CP_UTF8).

Вашим следующим камнем преткновения будет шрифт, который используется для консоли.Вам придется изменить его, но найти шрифт с фиксированной высотой и полным набором глифов для покрытия Unicode будет сложно.Вы увидите, что у вас есть проблема со шрифтом, когда вы получите квадратные прямоугольники на выходе.Вопросительные знаки - это проблемы с кодировкой.

3 голосов
/ 25 июля 2010

Почему вы хотите использовать UTF8 для внутреннего использования? Вы работаете с таким большим количеством текста, что использование UTF16 создаст необоснованные требования к памяти? Даже если бы это было так, вам, вероятно, все равно лучше использовать широкие символы и решать проблемы с памятью каким-либо другим способом (используя дисковый кеш, лучшие алгоритмы или структуры данных).

Ваш код будет намного чище и проще в использовании, если использовать внутренние символы, встроенные в Win32 API, и выполнять преобразования UTF8 только при чтении или записи нужных данных (например, файлов XML или API REST). *

Ваша проблема также может возникать в тот момент, когда вы выводите выходные данные на консоль, см .: Вывод Unicode-строк в консольном приложении Windows

Наконец, я не использовал библиотеку utfcpp, но преобразования в UTF8 довольно тривиальны для использования с использованием Win32 WideCharToMultiByte и MultiByteToWideChar с CP_UTF8 в качестве кодовой страницы. Лично я выполнял бы однократное преобразование и работал с текстом в UTF16, пока не пришло время выводить или переносить его в UTF8, если это необходимо.

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