Страницы

13 дек. 2012 г.

Кириллица в консольных приложениях

При написании консольных программ на языках C, C++ под Windows возникает проблема с отображением русских букв. Поэтому начинающие программисты часто делают вывод текста в своей программе транслитом, на ломанном английском, либо на каком-то промежуточном языке. Наверняка среди них популярно заблуждение о том, что русские буквы невозможно получить в принципе.

Несмотря на то, что с этой проблемой я столкнулся еще в своей самой первой программе, элегантное решение нашлось только сейчас. И знаете что? Выражать свои мысли на родном языке намного приятнее, и программа выглядит аккуратно.


Кстати, в линуксе такой проблемы нет. Там свои.

В семье Windows принято умалчивать о существовании каких-то там кодировок символов, поскольку это слишком сложно для рядового пользователя. Лучше ему ничего об этом знать, потребитель должен быть счастлив. Плох тот товар, который напрягает покупателя. Конечно же я утрирую, но доля истины в этом есть. К тому же, у рядового пользователя действительно не возникает проблем с кодировками. Зачем вам может понадобиться открывать текстовый файл, написанный кем-то под линуксом в кодировке KOI-8?

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

Ну да ладно. В Windows используется две кодировки: cp1251 и юникод (utf-8 или utf-16?). На самом деле есть еще третья — cp866, оставшаяся рудиментом от MS-DOS (поддержка которого прекратилась в 2000 г, между прочим). Именно она используется в консоли по сей день.

Можно еще упрекнуть винду в способе указывать окончания строк двумя байтами CR + LF вместо одного. Это же целый лишний байт тратится! Да и просто анахронизм.

Первый способ

Ради него я и затеял этот пост.

Все, что нам (вам) нужно сделать — перекодировать свои исходники в cp866. Чем? Я воспользовался notepad++. Более привычный мне редактор Sublime Text тоже умеет это делать.

Достоинства:

Никаких изменений в коде. Вам не придется подключать дополнительные библиотеки, писать лишние строки кода, менять язык с C на C++ ради использования замысловатой функции из windows.h.

Не надо менять консольный шрифт. Ваш друг, которому вы прислали на тестирование свою программу, гарантированно увидит русские буквы, независимо от шрифта в его консоли.

Полная работоспособность. Входные и выходные потоки — все работает как положено. Разумеется, в определенных рамках.

Недостатки:

Редактор или среда, в которой вы пишете, должна дружить с этой кодировкой. Текстовые файлы сами по себе не содержат никакой информации о кодировке символов, поэтому редакторы вынуждены ее угадывать. Чтобы не возникало недоразумений, хорошей манерой будет в начале файла писать что-то вроде:

//this file designed and commented in russian cp866 encoding int main() //программа, которая ничего не делает { return 0; }

Другие способы

  1. Прописать в начале волшебную строчку setlocale(LC_CTYPE, "rus"); — работает только с выходным потоком. Тем не менее, стоит взять на заметку. Это хорошая альтернатива первому способу.
  2. Делать преобразования для каждой строки через CharToOem( ). Не проверял, мне такое сразу не понравилось: надо подключать windows.h, теряется кроссплатформенность, код замусоривается лишними строками.
  3. Подключить windows.h, использовать SetConsoleCP( ) и SetConsoleOutputCP( ) — нужно менять шрифт на Lucida Console, который мне лично не очень; теряется кроссплатформенность.

Ссылки



обновлено 25.01.2013

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

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