Сообщений 23    Оценка 145 [+0/-1]         Оценить  
Система Orphus

Почему вместо русских букв в консольном приложении выводится мусор?

Автор: Алексей Кирюшкин

Версия текста: 1.0

Итак, Вы сваяли в Visual Studio что-то типа

#include "stdafx.h"

int main(int argc, char* argv[])
{
    printf("Привет всем!\n");
    return 0;
}

Запускаете сей шедевр на исполнение и видите

¦ЁштхЄ тёхь! 

и правильно! Текст программы Вы набирали в родном редакторе Visual Studio, используя кодовую страницу 1251, а вывод текста в консольном приложении идет с использованием кодовой страницы 866. Что же делать с этим безобразием? Как известно из любого безвыходного положенния есть по крайней мере 3 выхода. Рассмотрим их по-порядку.

Выход 1

Набрать текст программы в редакторе любого консольного файл-менеджера.

А как же подсветка синтаксиса, вывод по F1 справки по выбранной функции и прочие маленькие прелести, скрашивающие безрадостную жизнь простого программиста? Нет, это выход не для нас.

Выход 2

Если Вы начали писать консольную программу с нуля, он может Вам подойти. Перепишем наш маленький шедевр вот так:

#include "stdafx.h"
#include "windows.h"

int main(int argc, char* argv[])
{
    char s[]="Привет всем!";
    CharToOem(s,s);
    printf("%s\n", s);
    return 0;
}

Ключевое слово здесь CharToOem - именно эта функция и преобразует нашу строку в нужную кодовую страницу. С выводом у нашей программы теперь все нормально.

Но встает следующий вопрос - что делать, если надо перекомпилировать в консольное Windows-приложение Вашу старую DOS-программу на 100000 строк, написанную на Borland C++ 3.1, в которой такая ситуация встречается в каждой второй строке. А ведь придется еще подгонять ее под MS-компилятор, да и пару кусочков кода хочется соптимизировать...

Здесь пожалуй имеет смысл применить ход конем, в смысле

Выход 3

Заменяем родную переключалку раскладки клавиатуры Windows на RusLat от Сергея Быкова, а для редактора Visual Studio изменям шрифт (Tools->Options->Format->Source Windows->Font) на любой шрифт для досовских окошек, например Terminal. Переключаем клавиатуру на раскладку DOS-CP866 (есть в RusLat'е и такая, наряду с KOI-8 и Russian Translit) и можно работать с текстом нашей досовской программы в редакторе Visual Studio. Русские буквы в досовской кодировке правильно читаются, т.к. установлен соответствующий шрифт и их можно редактировать, т.к. для клавиатуры установлена досовская раскладка.

Нужно пожалуй упомянуть и еще

Выход 4

Впрочем, это и не выход даже, а так, тупичок. Работает он только, если соблюдены 3 условия:

Если все эти 3 условия соблюдены, достаточно вставить вначале программы вызов функции SetConsoleOutputCP, задав в качестве параметра нужную нам кодовую страницу:

#include "stdafx.h"
#include "windows.h"

int main(int argc, char* argv[])
{
    if (!SetConsoleOutputCP(1251))
    {
        // попытка установить нужную страницу закончилась неудачно
        // выводим причину ошибки
        char msg[300];
        FormatMessage(FORMAT_MESSAGE_IGNORE_INSERTS 
            | FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(),  
            0, msg, sizeof(msg) - 1, 0);
        // если версия Windows локализованная то ошибка будет
        // на русском языке, поэтому 
        CharToOem(msg, msg);
        printf("SetConsoleOutputCP Error: %s\n", msg);
        return 1;
    }

    // дальше весь вывод пойдет в установленной кодовой странице
    printf("Привет всем!\n");
    printf("И еще раз привет всем!\n");
    return 0;
}

Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.
    Сообщений 23    Оценка 145 [+0/-1]         Оценить