Ещё раз про 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 :)
Вот как-то так.
При этом, иногда мешать два способа всё же придётся. Например, если нужно обрабатывать ввод русских букв с помощью сишных функций проверки класса символов.
Вот такой код, при вводе русских букв, не будет корректно проверять, введена ли буква:
#include <iostream> #include <cstdlib> #include <cctype> #include <Windows.h> using namespace std; int main() { //setlocale(LC_ALL,"Rus"); SetConsoleCP(1251); SetConsoleOutputCP(1251); char ch; cin >> ch; if (isalpha((unsigned char)ch)) cout << "is alpha" << endl; else cout << "no alpha" << endl; system("pause"); return 0; }
Если же раскомментарить строчку с setlocale
, то будет.
13.09.2015, 14:20 [68820 просмотров]