При написании консольных программ на языках C, C++ под Windows возникает проблема с отображением русских букв. Поэтому начинающие программисты часто делают вывод текста в своей программе транслитом, на ломанном английском, либо на каком-то промежуточном языке. Наверняка среди них популярно заблуждение о том, что русские буквы невозможно получить в принципе.
Несмотря на то, что с этой проблемой я столкнулся ещё в своей самой первой программе на C, элегантное решение нашлось только сейчас. И знаете что? Выражать свои мысли на родном языке намного приятнее, и программа выглядит аккуратно.
В семье Windows принято умалчивать о существовании каких-то там кодировок символов, поскольку это слишком сложно для рядового пользователя. Лучше ему ничего об этом знать, потребитель должен быть счастлив. Плох тот товар, который напрягает покупателя. Конечно же я утрирую, но доля истины в этом есть. К тому же, у рядового пользователя действительно не возникает проблем с кодировками. Зачем вам может понадобиться открывать текстовый файл, написанный кем-то в кодировке KOI-8?
На практике получается, что кракозябры видели все, а откуда они берутся и как их вылечить знают немногие.
Ну да ладно. В Windows используется две кодировки: cp1251 и юникод. На самом деле есть ещё третья — cp866, оставшаяся рудиментом от MS-DOS. Именно она используется в консоли по сей день.
Первый способ
Все, что нам (вам) нужно сделать — перекодировать свои исходники в cp866. Чем? Я воспользовался notepad++. Более привычный мне редактор Sublime Text тоже умеет это делать.
Достоинства:
Никаких изменений в коде. Вам не придется подключать дополнительные библиотеки, писать лишние строки кода, менять язык с C на C++ ради использования замысловатой функции из windows.h
.
Не надо менять консольный шрифт. Ваш друг, которому вы прислали на тестирование свою программу, гарантированно увидит русские буквы, независимо от шрифта в его консоли.
Полная работоспособность. Входные и выходные потоки — всё работает как положено. Разумеется, в определённых рамках.
Недостатки:
Редактор или среда, в которой вы пишете, должна дружить с этой кодировкой. Текстовые файлы сами по себе не содержат никакой информации о кодировке символов, поэтому редакторы вынуждены её угадывать. Чтобы не возникало недоразумений, хорошей манерой будет в начале файла писать что-то вроде:
//this file is designed and commented in russian cp866 encoding
int main() //программа, которая ничего не делает
{
return 0;
}
Другие способы
Прописать в начале волшебную строчку
setlocale(LC_CTYPE, "rus");
— работает только с выходным потоком. Тем не менее, стоит взять на заметку. Это хорошая альтернатива первому способу.Делать преобразования для каждой строки через
CharToOem()
. Не проверял, мне такое сразу не понравилось: надо подключатьwindows.h
, теряется кроссплатформенность, код замусоривается лишними строками.Подключить
windows.h
, использоватьSetConsoleCP()
иSetConsoleOutputCP()
— нужно менять шрифт на Lucida Console, который мне лично не очень; теряется кроссплатформенность.
Ссылки
- hardforum → FAQ по C/C++ — описан третий способ.
- Блог Cpp Studio → кириллица в консоли — подробно описаны второй и четвертый способы.
- Блог C++ для людей — пост на ту же тему, есть несколько хороших ссылок.