Страницы

Поиск по вопросам

пятница, 27 декабря 2019 г.

C++11 string literal u8

#cpp #unicode


Решил написать небольшой пример:

#include 

int main()
{
    std::cout << u8"это строка6" << std::endl;
    return 0;
}


Устанавливаю в консоли кодовую страницу с помощью следующей команды:
chcp 65001

Выполняю программу, и получаю следующий вывод:

��то строка6


Почему первый символ отобразился неправильно?
Судя по выводу, при использовании литерала u8, BOM в начало не добавляется.
Это кодировка 65001 думает, что в начале идет BOM, пытается прочитать его,
а остальное выводит нормально. Тогда хотелось бы найти кодировку UTF-8 без BOM.

Дополнения:
Файл сохранен также в utf8 without BOM. Если перенаправить в файл, то запишется нормально.
Компилятор Mingw с версией gcc 5.0. Система - Windows.
    


Ответы

Ответ 1



Советую вам не использовать utf-8 при выводе в консоль на Windows (режим utf-8 имеет баги), вместо этого пользоваться "широкими" потоками (подробнее про использование юникода в Windows) #include #include #include #include #include // std::wcerr std::wstring strtows(const std::string &str, UINT codePage) { std::wstring ws; int n = MultiByteToWideChar(codePage, 0, str.c_str(), static_cast(str.size()), NULL, 0); if (n) { ws.resize(n); if (MultiByteToWideChar(codePage, 0, str.c_str(), static_cast(str.size()), &ws[0], n) == 0) ws.clear(); } return ws; } std::string wstostr(const std::wstring &ws, UINT codePage) { // prior to C++11 std::string and std::wstring were not guaranteed to have their memory be contiguous, // although all real-world implementations make them contiguous std::string str; int srcLen = static_cast(ws.size()); int n = WideCharToMultiByte(codePage, 0, ws.c_str(), srcLen, NULL, 0, 0, NULL); if (n) { str.resize(n); if (WideCharToMultiByte(codePage, 0, ws.c_str(), srcLen, &str[0], n, 0, NULL) == 0) str.clear(); } return str; } std::string WstringToUtf8(const std::wstring &str) { return wstostr(str, CP_UTF8); } std::wstring Utf8ToWstring(const std::string &str) { return strtows(str, CP_UTF8); } int main(int argc, char *argv[]) { _setmode(_fileno(stdout), _O_U16TEXT); std::wcout << Utf8ToWstring(u8"это строка6") << std::endl; return 0; }

Комментариев нет:

Отправить комментарий