Страницы

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

четверг, 19 декабря 2019 г.

Отображение кириллицы в CLion

#cpp #кириллица #clion


Нужна помощь: не отображается кириллица в терминале CLion. Вот так выглядит надпись
"Привет, Мир!":


  ╨Я╤А╨╕╨▓╨╡╤В, ╨Ь╨╕╤А!


Вот что будет с кодировкой windows-1251:


  ╧ЁштхЄ, ╠шЁ!

    


Ответы

Ответ 1



Почему так происходит? CLion по дефолту использует UTF-8 для хранения файлов с исходным кодом. Строка "Привет, Мир!" будет представлять собой последовательность (в файле с исходником): D0 9F D1 80 D0 B8 D0 B2 D0 B5 D1 82 2C 20 D0 9C D0 B8 D1 80 21 Как видите, на 12 символов исходной строки, получили 21 байт (т.к. кириллические символы занимают больше одного байта). Компилятор GCC по умолчанию читает исходники в кодировке UTF8, если не указать другую через ключ -finput-charset. Таким образом эта последовательность байтов в неизменном виде сохранится в исполняемый файл. При запуске программы на исполнение, CLion использует стандартный cmd.exe, который по умолчанию скорей всего у вас работает в кодировке CP866. В которой наша последовательность байтов будет отображена как: ╨Я╤А╨╕╨▓╨╡╤В, ╨Ь╨╕╤А! (что вы и видите в терминале CLion) Что делать? Вариант 1 Сменить кодировку файла на IBM866 (то же, что и CP866) (настройки - File Encodings) (сам файл перекодировать, если там уже был текст на русском). Теперь кириллица будет сохраняться в файле с исходным текстом в кодировке CP866 (один байт на символ), в том же виде попадать в исполняемый файл и нормально отображаться в консоли CLion. Разумеется, использовать CP866 в 17-м году, без особых на то оснований, это некультурно. Кроме того придется ограничить себя только символами из CP866. Вариант 2 Вставить в начало свой программы: system("chcp 65001"); или (потребует #include ): SetConsoleOutputCP(CP_UTF8); Консоль переключится в UTF-8, все будет отображаться как надо. Но только при использовании низкоуровневых операций вывода типа puts("Привет, Мир!");. Если выводить через std::cout, то возможен вывод типа ��ривет, Мир!. Это связано с тем, что Windows API для вывода в консоль ожидает видеть в каждом вызове законченную строку. И если оператор basic_ostream::operator<<(char*) для символа 'П' выполнит два API вызова (с D0 и 9F), то они не сольются в одну букву 'П', а будут интерпретированы и отображены как два разных символа (��). Предостережение При использовании UTF-8 в своей программе, например при хранении в std::string, следует помнить, что операции над строками могут дать не очевидные результаты (т.к. один символ теперь может занимать от 1 до 4 байтов). Кроме вывода, аналогичные проблемы ожидают и при вводе из std::cin. Таким образом, единственное прозрачное решение для Windows (даже десятки), пока остается использование латиницы.

Ответ 2



Похоже вы компилируете проект с помощью MinGW, у меня была такая же проблема с кодировками в консоли СLion (которая выводится внизу при выборе "Run" в панели инструментов справа сверху), также пробовал разные кодировки, результат один не читаемые "крякозаблики". Правда когда используешь cp-1251 и запускаешь программу в консоли Windows (CMD), то тоже выводится всё хорошо (правда это не очень удобно, надо сделать больше телодвижений). На другом ноутбуке попробовал использовать CLion вместе с CygWin и всё стало нормально при настройках кодировки по умолчанию, я использовал UTF-8.

Ответ 3



Для Clion: Cygwin - при установке в выборе пакетов нужно найти и отметить всякие cmake, GDB и прочие, кем-нибудь рекомендуемые к установке. Сlion - File - Settings - Editor - File Encodings: IDE Encoding, Project Encoding, main.cpp (Ваш исполняемый файл) - UTF-8, Default encoding for properties files - IBM866 В окне редактора внизу - UTF-8. Включить заголовочный файл Windows.h SetConsoleCP(866); SetConsoleOutputCP(866);

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

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