textpub.neocities.org . [ записки: обучаюсь C++ ]

Из моих записок про самообучение C++. Дата первой публикации: 03.02.2019.

Консольная программа выдает кракозябры 3.3

Второй способ решения проблемы (окончание)

Начало можно прочитать в этой записи, вторая часть, начало и продолжение третьей части. Если во второй части мы подстраивали выводимый в командную строку Windows 7 (cmd.exe) текст под кодировку из группы кодировок OEM (866), то здесь настраиваем из нашей программы кодировку командной строки под нужную нам кодировку из группы кодировок ANSI (1251). Это тоже можно сделать несколькими способами, один из которых мы рассмотрели в начале третьей части, второй — в продолжении третьей части.

Функция system и команда chcp

Функция system (ее описание на сайте компании Microsoft) входит в стандарт языка Си и стандарт языка С++ и используется для передачи команд интерпретатору командной строки (в нашем случае — cmd.exe).

Для решения проблемы кракозябр можно применить команду chcp интерпретатора командной строки (ее описание на сайте компании Microsoft). С помощью этой команды можно переключить кодировку консоли на нужную. В описании этой команды приведен неполный список идентификаторов кодовых страниц, более полный можно посмотреть здесь.

При использовании функции system и команды chcp следует учитывать все замечания, которые были сделаны в предыдущей записи касательно функций SetConsoleOutputCP и SetConsoleCP из набора Windows API. А именно: для работы этого способа требуется настроить шрифт консоли на один из предложенных в окне свойств консоли моноширинных юникодных шрифтов (вручную или программно, подробности описаны в предыдущей записи); способ работает при переключении языка системы (system locale); требуется аккуратность при совместном использовании с функцией переключения локали setlocale.

Возьмем программу из предыдущей записи; уберем подключение windows.h, так как функция system, как уже упоминалось выше, входит в стандарт языка C++; и заменим вызов функций SetConsoleOutputCP и SetConsoleCP на вызов функции system. Получим следующее (шрифт Lucida Console в консоли выберем вручную, если он еще там не выбран):

#include <iostream>
using namespace std;
int main()
{
    char str[80]; // для вводимой строки
    struct lconv * lc; // структура с настройками локали

    // передаем команду интерпретатору командной строки
    system("chcp 1251");

    cout << "ANSI  : " << "У каждой эпохи свой язык\n"; // 1251
    cout << "In    : "; cin.getline(str, 80);
    cout << "Out   : " << str << "\n";

    // вывод обозначения валюты при локали "Английский (США)"
    cout << "Валюта: ";
    setlocale(LC_ALL, "en-US"); lc = localeconv();
    cout << lc->int_curr_symbol << "\n";

    // вывод обозначения валюты при локали "Русский (Россия)"
    setlocale(LC_ALL, "ru-RU"); lc = localeconv();
    cout << "Валюта: ";
    cout << lc->int_curr_symbol << "\n";

    return 0;
}

Результат работы программы:

На картинке видно, что кроме переключения кодировки команда chcp печатает в консоль после переключения кодировки сообщение «Текущая кодовая страница: 1251». Для подавления вывода этого сообщения можно использовать перенаправление вывода на несуществующее устройство nul:

    system("chcp 1251 > nul");

Результат работы программы после внесения вышеуказанного изменения:

Либо для подавления вывода ненужного сообщения можно сразу после переключения кодировки вообще очистить консоль с помощью команды cls:

    system("chcp 1251"); // переключить кодировку
    system("cls"); // очистить окно консоли

Результат работы программы после внесения вышеуказанного изменения:

textpub.neocities.org . [ записки: обучаюсь C++ ]