Ещё раз про 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 [74845 просмотров]

