#cpp #unicode
Решил написать небольшой пример: #includeint 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; }
Комментариев нет:
Отправить комментарий