Setconsolecp 1251 setconsoleoutputcp 1251 что это

от admin

Setconsolecp 1251 setconsoleoutputcp 1251 что это

БлогNot. Ещё раз про setlocale и SetConsoleCP/SetConsoleOutputCP в Studio.

Ещё раз про setlocale и SetConsoleCP/SetConsoleOutputCP в Studio.

Типовая проблема начинающих — «кракозябры» вместо кириллицы при разработке консольных приложений в MS Visual Studio.

Решения известны, но с ними тоже бывают нюансы. В частности, не надо мешать в одной программе setlocale — стандартную функцию из <clocale> и SetConsoleCP / SetConsoleOutputCP — пропиетарные функции от Microsoft из <windows.h> . Что они делают — одному микрософту известно, скорее всего, мешают работать setlocale 🙂

При этом, если указываем кодировку 1251, то при использовании микрософтовских функций необходимо выбрать в свойствах консоли шрифт Lucida Console, а для стандартной setlocale может и не помочь.

Методом научного тыка можно сделать такие выводы:

  • SetConsoleOutputCP() устанавливает кодировку вывода на консоль;
  • SetConsoleCP() устанавливает кодировку ввода из консоли и из редактора кода;
  • setlocale(LC_ALL,».1251″) проверяет, какая кодировка установлена сейчас, и если она не 1251, то меняет ее на 1251, а если уже 1251, то ничего не делает.

Поэтому, если уже установлена кодировка ввода из редактора функцией SetConsoleCP(1251) , то после неё setlocale() ничего менять не будет, и попросту выведет символы в кодировке CP866, решив, что они и так уже в windows 1251.

Если же уже выполнена функция SetConsoleOutputCP(1251) , то setlocale() проверит, какая кодировка ввода установлена, и обнаружит, что кодировка ввода по-прежнему CP866, поэтому она возьмет номера этих уже преобразованных символов (с помощью SetConsoleOutputCP(1251) ), но из кодовой таблицы cp866, и выведет символы с этими номерами из таблицы windows 1251 🙂

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

Вот такой код, при вводе русских букв, не будет корректно проверять, введена ли буква:

Кириллица в консоли

Самый лучший способ изучения языка программирования С++ — это составление консольных программ. Структура консольного проекта максимально упрощена, так как нет графического режима, для которого необходимо подключение файлов ресурсов, классов и прочего, прочего. При составлении программы может понадобиться вывести некоторое текстовое сообщение в консоль. И если это сообщение написано на латинице, то в командной строке Windows оно будет отображаться корректно. А если текстовое сообщение написано на кириллице, то вместо передаваемого сообщения, будет отображаться непонятная последовательность букв и символов (см. Рисунок 1). Реализуем программно то, что мы хотим сделать.

Программа передаёт сообщение Кириллица в консоли в командную строку Windows, и на этом завершает свою работу (см. Рисунок 1).

Рисунок 1 — Кириллица в консоли

В результате, вместо передаваемого сообщения отображается непонятная последовательность символов, называемая — козяблики. Возникает вопрос: «Почему так происходит?». Чтобы понять природу происхождения так называемых козябликов, необходимо обратиться к теме — представление символов букв в компьютерах.

Природа вычислительных машин такова, что они могут работать только с числами. Поэтому, для представления букв или символов необходимо их закодировать, то есть каждой букве или символу присвоить определённое число, которое будет являться его кодом. Так образовались таблицы кодирования символов. В связи с тем, что в мире существует более 2,5 тысяч языков, то для каждого алфавита создавались свои таблицы кодирования символов, вот почему существует большое количество таблиц кодирования символов. Так как мы программируем под Windows, то нас будут интересовать такие кодировочные таблицы: cp866, cp1251 и utf-8(стандарт Unicode). Хотя уже давно разработан единый стандарт кодирования символов — Unicode, в Windows до сих пор используются несколько кодировочных таблиц, а именно — cp866, cp1251. Использование нескольких таблиц кодирования символов и является причиной появления козябликов, вместо сообщения Кириллица в консоли .

Таким образом стандарт Unicode присваивает каждому символу уникальный код, независимо от языка. Сейчас Unicode считается лучшим стандартом кодирования символов. Вернёмся к нашей проблеме — вывод кириллицы в консоль.

Так уж повелось, в командной строке Windows кодировка символов соответствует стандарту cp866. То есть все символы в командной строке Windows закодированы по кодировочной таблице cp866. Причём поменять кодировку в командной строке Windows нельзя. Просмотреть стандарт кодирования символов в консоли можно, с помощью команды GRAFTABL (см. Рисунок 2).

Рисунок 2 — Кириллица в консоли

Во всех русскоязычных Windows кодировка cp1251 является стандартной 8 — битной кодировкой. И при создании проекта в MVS2010 этот стандарт кодирования символов наследуется проектом, то есть программой. Хотя кодировку для проекта в MVS2010 можно легко поменять, это не решает проблемы, так как консоль понимает только одну кодировку cp866, которой в MVS нет. В итоге, получается, что программа передаёт коды символов сообщения стандарта cp1251. Командная строка принимает эти коды и переводит их в символы, но уже по стандарту cp866, так как другого стандарта не знает. В итоге сообщение передано в консоль, но символы интерпретированы не правильно, вот так и появляются козяблики.

Решить данную проблему можно только одним способом — перед тем, как передать текст в консоль, необходимо его перекодировать в стандарт кодирования символов cp866. Существует несколько способов преобразования кодов знаков из одного стандарта в другой, мы воспользуемся самым простым — настройка локали.

Локаль — это набор параметров: набор символов, язык пользователя, страна, часовой пояс и др. Локаль необходима для быстрой настройки пользовательского интерфейса, в зависимости от географического положения. В С++ есть функция setlocale() , которая выполняет перекодировку символов в соответствии с требуемым языком. Эта функция определена в заголовочном файле <clocale> . Переделаем программу, которая передает сообщение Кириллица в консоли в командную строку windows.

В чём разница способов подключения кириллицы?

Здравствуйте! Учу С++, программирование и в целом развиваюсь в сфере IT.

Сегодня обнаружил в консольке винды команду echo, позволяющую выводить на экран некую надпись.
99lWUFp5in8.jpg
Решил попробовать вызвать эту команду через C++ и функцию system. Хочу заметить, что всегда использую вариант подключения кириллицы через SetConsoleCP(1251); из windows.h, как и в коде ниже.

Результатом выполнения программы оказались кракозябры, вылезающие при неподключённой кириллице.
mjQwKFifRvI.jpg
Однако, когда я решил использовать в коде функцию setlocale, вывод на экран стал соответствовать моей цели.

8XblUj_u3tc.jpg
Исходя из опытов выше, возникает вопрос: а чем различаются эти два варианта подключения кириллицы к проекту? Если что, я спрашиваю не только про результат работы, но и про сами процессы, происходящие в системе при использовании этих функций.
Заранее спасибо за ответ.

  • Вопрос задан более трёх лет назад
  • 3132 просмотра
  • Facebook
  • Вконтакте
  • Twitter

Практически всем. На самом деле, у вас есть две сущности — ваша программа и терминал. Ваша программа читает данные из stdin и пишет в stdout/stderr. Терминал же занимается тем, что отображает данные на экран. Для вас критически важно, чтобы программа передавала данные в той кодировке, в которой их ожидает увидеть терминал.

Соотвественно, когда вы вызываете SetConsoleOutputCP(1251) , вы говорите терминалу «ожидай данные в кодировке СР1251». Это плохо по нескольким причинам:

  • Это чисто виндова функция. Она не переносима на другие платформы
  • СР1251 — однобайтовая кодировка и ее лучше не использовать в 21 веке. Нужен юникод.
  • Другие программы, работающие в этом же терминале (например echo) не знают что вы поменяли кодировку терминала. Потому вы и видите мусор.

Когда вы вызываете setlocale — вы говорите своей программе «возьми настройки кодировки из окружения и выдавай текст в ней». В результате вы подстраиваетесь под терминал и используете ту кодировку, в которой он работает. Скорее всего это будет юникод. В этом варианте все минусы превращаются в плюсы — это переносимо, это юникод, остальные программы будут работать нормально.

Кстати, вызывать setlocale с параметром Russian не совсем верно. Нужно использовать пустую строку -«». Интересно, что я уже второй раз вижу на тостере именно «Russian». Кажется, где-то по рунету гуляет неправильный пример.

Читать:
Когда не можешь открыть галерею

Русские символы(буквы) при вводе/выводе в консоль на C++

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

Возникла проблема с отображением русских букв

Если нужно быстрое решение данной проблемы, то можно сразу пролистать вниз, ибо сначала я расскажу о том, как возникла эта проблема у меня и о том, как я искал решение.

На языке C++ программирую под ОС Linux, использую компилятор GCC. С проблемой неправильного отображения русских букв я не сталкивался. В момент написания статьи я нахожусь далеко от своего компьютера, могу довольствоваться лишь скромненьким ноутбуком с установленной ОС Windows Seven. Захотелось покодить и я установил на него интегрированную среду разработки Dev-C++ 5.10(использует компилятор TDM-GCC 4.8.1 на базе GCC 4.8.1). Кстати, она уже официально не поддерживается, но существует форк Orwell Dev-C++, который обновляется по сей день. Установив, я запустил и для пробы написал простую программку, которая отображает текст «Привет, мир!». Но поздороваться она с миром так и не смогла, а лишь сказала что-то непонятное на древнеегипетском. После перелопачивания некоторых форумов и сайтов я нашел множество советов, но основная масса не способна была решить её полностью, образовывались подводные камни о которых расскажу далее.

После написания, компиляции и запуска такой программы:

Можно получить примерно такой результат

Вывод кракозябр в консоль

Сразу понятно, что на приветствие это совсем не похоже.

После прочтения кучи советов стало понятно, что большая часть советов предлагала решить проблему функцией setlocale(), которая находится в заголовочном файле <clocale>.

Последовав совету и усовершенствовав программу таким образом:

Дополнительно: можно было написать setlocale(0, «») и результат был бы аналогичным, при условии, что в настройках ОС язык системы русский.

На вывод я получил следующий результат

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

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

Коль уж так, я решил вновь внести изменения в программу, пусть она поздоровается со мной по имени.

Но в результате я получил не приветствие

Оскорбление на древнеегипетском?

Как видно, она не смогла назвать моего имени.

Поискав информацию в сети, я узнал о том, что setlocale() не работает с потокоми ввода/вывода, а то есть с cin,cout,etc. Выходит, что нужно искать альтернативные способы решения данной проблемы, которые предлагались на других сайтах.

Решение проблемы с отображением русских букв в консоли

По-другому решить проблему можно было воспользовавшись функциями SetConsoleCP() и SetConsoleOutputCP() с аргуменом 1251 в обеих. Эти функции требуют подключения заголовка <Windows.h>, практически в каждом компиляторе под Windows он имеется, проблем не будет.

Усовершенствовал программу таким образом

На вывод получил

Вновь кракозябры в консоли

Вновь кракозябры в консоли

Снова что-то непонятное. Но решение, как оказалось, находилось очень близко. У функций SetConsoleCP() и SetConsoleOutputCP() есть небольшой недостаток — они работают только со шрифтом Lucida Console. В консоли же по умолчанию стоит шрифт Consolas, либо точечные шрифты. Следующим этапом сделать нужно вот что. Находясь в консоли нажать кнопку Cmd или нажать на значек программы в левом верхнем углу(Перед D:\… в названии), то есть вызвать контекстное меню окна. Далее нажать «Свойства».

Контекстное меню консоли

Контекстное меню консоли

Далее появится окно с настройками, там необходимо выбрать шрифт Lucida Console.

Свойства консоли Windows

Свойства консоли Windows

И нажать на кнопку ОК.

После такой процедуры я вновь запустил программу и…

Работа программы

Да! Она поздоровалась со мной по имени на русском языке.

Данный способ помог решить мне проблему с отображением русских символов в консоли Windows, надеюсь, что кому-нибудь еще он тоже поможет. Спасибо за внимание.

Для вас это может быть интересно:

Русские символы(буквы) при вводе/выводе в консоль на C++ : 29 комментариев

Блин все делаю как показано но все равно не получается в свойствах консоли установлен шрифт Lucida Console может поможете)
Пишу:
#include
#include
#include

using namespace std;

int main()
<
setlocale(LC_ALL,»Russian»);
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
cout << "Привет, Мир!";
return 0;
>

  1. Nicknixer Автор записи 07.12.2015

Проверил у себя — всё работает и отображает верно. Попробуйте набрать такую же программу, как на рисунке здесь http://nicknixer.ru/?p=349

Строчка setlocale(LC_ALL,»Russian») не нужна, без нее все работает.

тебе нужно понять что тебе нужно, если только вывести текст то оставь setlocal(LC_ALL, «Russian»)
ну а если у тебя будет переменная напримере кода
int main()
<
char name [12];
cout << "как тебя зовут?";
cin << name;
cout << "привет, " << name;
return 0;
>
то получится что ничего не получится, в этом случае используй setconsolecp(1251); setconsoleoutputcp(1251); и тогда всё будет корректно отображаться. по поводу программы ide я использую visual studios 2019 и всё нормально работает

В консоли 866 кодовая страница. Можно проще — Creator — Настройки — редактор — кодовая страница 866. Заработает самая первая программа.

Спасибо за 866 кодовую таблицу, все заработало.

Мучался 2 часа с выводом русских букв!
Перечитал кучу пустых советов.
Наконец-то.
Этот— самый толковый способ сделать так, чтобы все работало, и писало по русски!!
Благодарю Вас.

  1. Nicknixer Автор записи 14.10.2016

Я рад тому, что это помогло мне, Вам и другим людям.

Вижу, что не только в вебе проблема с отображением русских букв. PHP- программисты с вами!

Большое человеческое спасибо!
Очень помогли дельным советом. Всё работает как надо!

Спасибо!по полочкам и правильно всё разложено)

На мой взгляд, самый простой и действенный способ вывода русских букв в консоли Windows: писать исходники в ее родной кодировке, т. е. в OEM866 и проблем никаких не возникнет. Тем более, что почти все текстовые редакторы ее поддерживают. Для удобства можно установить эту кодировку по умолчанию в тот же Notepad++.
И не надо танцевать с бубном, подключать заголовки, использовать дополнительные функции, менять шрифты и т.д.

Спасибо, дай те бог здоровья!!

Благодарю за эти советы, они действующие, доходчивые. Ушла минута на то, что долго не мог сделать

6 часов искал ответ!Спасибо !

Лайфхак от «Специалист»
После main
system(«chcp 1251 > nul»);

Имеется ввиду после фигурных скобок, т.е. в тело программы

Вообще-то setlocale() и всё вокруг неё касается преобразований WCHAR -> BYTE -> WCHAR у CRT функций (ну например если выводить тот-же самый «Привет мир» вот так:

setlocale( LC_ALL, «.OCP» );
wprintf(L»Привет мир!»);

То будет уже профит.
В свою очередь SetConsoleOutputCP() нужна примерно для того-же — на Винде с чужой кодировкой выводить юникодные строки кирилицей.
ну а так Taras Lavrov верно указал как это для неюникодных программ делается.

Спасибо большое!Очень помогло.С начала про поток вывода узнал где то недели 2 назад, вчера заинтересовало почему поток ввода не работает. Менее минуты и вуаля. Надеюсь ругаться там не будет никто на счёт заголовочных файлов, но…ОС у всех разные, преобразователи (компиляторы) разные. Вот поэтому и советы для всех разные. Кому то кодировку сменить, а многим многим остальным дополнительные код надо писать. Может когда напишем собственную ОС(хотя кое что такое у нас было когда то давно) тогда ничего этого не надо будет. Автору статьи большое спасибо ещё раз. Русский язык стараюсь вписать куда угодно лишь бы было по русски. Надеюсь, это никого не задевает

Похожие статьи