Проблема WideCharToMultiByte

У меня есть прекрасные функции из моего предыдущего вопроса, которые прекрасно работают, если я делаю это:

wstring temp;
wcin >> temp;

string whatever( toUTF8(getSomeWString()) );

// store whatever, copy, but do not use it as UTF8 (see below)

wcout << toUTF16(whatever) << endl;

Оригинальная форма воспроизводится, но промежуточная форма часто содержит дополнительные символы. Если я войду, например, àçé в качестве ввода и добавить cout << whatever Скажите, я получу ┬à┬ç┬é в качестве вывода.

Могу ли я использовать эту строку для сравнения с другими, полученными из источника ASCII? Или спросили иначе: если бы я вывел ┬à┬ç┬é через UTF8 Cout в Linux, будет ли это читать àçé? Содержимое байта строки àçé, читайте в UTF8 linux cin, точно так же, как то, что получает Win32 API?

Спасибо!

PS: причина, по которой я спрашиваю, заключается в том, что мне нужно много использовать строку для сравнения с другими значениями чтения (сравнение и объединение...).

2 ответа

Решение

Давайте начнем с того, что я говорю, что кажется, что просто нет способа вывести текст UTF-8 на консоль в Windows через cout (при условии, что вы компилируете с Visual Studio). Однако, что вы можете сделать для своих тестов, это вывести текст UTF-8 через Win32 API fn WriteConsoleA:

if(!SetConsoleOutputCP(CP_UTF8)) { // 65001
    cerr << "Failed to set console output mode!\n";
    return 1;
}
HANDLE const consout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD nNumberOfCharsWritten;
const char* utf8 = "Umlaut AE = \xC3\x84 / ue = \xC3\xBC \n";
if(!WriteConsoleA(consout, utf8, strlen(utf8), &nNumberOfCharsWritten, NULL)) {
    DWORD const err = GetLastError();
    cerr << "WriteConsole failed with << " << err << "!\n";
    return 1;
}

Это должно вывести:Umlaut AE = Ä / ue = ü если вы настроили консоль (cmd.exe) на использование шрифта Lucida Console.

Что касается вашего вопроса (взято из вашего комментария), если

преобразованная в Win23 API строка совпадает с необработанной строкой UTF8 (linux)

Я скажу да: учитывая последовательность символов Unicode, это представление UTF-16 (Windows wchar_t), преобразованное в представление UTF-8 (char) через WideCharToMultiByte Функция всегда будет выдавать одну и ту же последовательность байтов.

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

Я сомневаюсь, что Cout UTF8 в linux будет производить тот же правильный вывод, если только это не будут обычные значения ASCII, поскольку формы кодирования UTF-8 UTF8 двоично-совместимы с ASCII для кодовых точек ниже 128, и я предполагаю, что UTF16 следует после UTF8 аналогичным образом,

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

Другие вопросы по тегам