Страницы

Поиск по вопросам

пятница, 27 декабря 2019 г.

Русский язык в исходном коде в Dev C++ [дубликат]

#windows #cpp


        
             
                
                    
                        
                            This question already has answers here:
                            
                        
                    
                
                        
                            Русский язык в консоли
                                
                                    (4 ответа)
                                
                        
                                Закрыт 3 года назад.
            
                    
Я недавно начал изучать С++, у меня есть компилятор Dev C++. Когда я делаю 

std::cout<<"Привет!"; 


то получается абракадабра! А если перебираю символы циклом, то русские буквы отображаются
правильно. Я думаю проблема в различии кодировок dos и windows. Кто знает какие-нибудь
примочки для Dev C++ (типа keycyr для pascal) или операторы/функции/процедуры C++ позволяющие
сменить кодировку std::cout.
    


Ответы

Ответ 1



С setlocale() по науке правильно, но если локализация кривовата (как у меня на этой машине), то не работает. В Windows есть 2 функции, CharToOem(char, char) и OemToChar(char, char) для перевода cp-1251 в cp-866 (консоль) и обратно. Пример: #include #include #include #include main () { char str[1000], buf[1000]; int itty = isatty(fileno(stdin)), otty = isatty(fileno(stdout)); strcpy(str, "привет"); if(otty) CharToOem(str, str); puts(str); fgets(str, 1000, stdin); if (itty) OemToChar(str, str); str[strlen(str) - 1] = `\0`; if (strstr("привет", str)) strcpy(buf, "да, часть от 'привет'"); else strcpy(buf, "такого нет в слове 'привет'"); if(otty) CharToOem(buf, buf); puts(buf); } В программе набрано в cp-1251 (она же ANSI). При вводе с консоли, независимо от setlocale() придется переводить кодировку. Также обратите внимание, что параметры командной строки, набранные в консоли поступают в программу в кодировке cp-1251!!! Кодировка в файлах обычно подразумевается в cp-1251, это надо учитывать при переадресации (>) вывода (stdout, stderr). Я продемонстрировал в примере, как это можно делать. UPDATE @insolor дал замечательный ответ как правильно программировать работу с русскими буквами в консоли Windows, используя стандартные функции SetConsoleCP(1251) и SetConsoleOutputCP(1251). В обсуждении (комментариях) к его ответу можно найти различные детали, в частности установку русского шрифта. Похоже его ответ прошел незамеченным для некоторых участников форума. Поэтому я решил привести функцию, вызов которой в самом начале упрощает программирование ввода/вывода русских букв в Windows и пример ее использования. cons1251.c #include static int oldin = 0, oldout = 0; static void exitfunc() { SetConsoleCP(oldin); SetConsoleOutputCP(oldout); } void cons1251 () { if (oldin) return; atexit(exitfunc); oldin = GetConsoleCP(); oldout = GetConsoleOutputCP(); SetConsoleCP(1251); SetConsoleOutputCP(1251); } rustest.c #include // русский текст в кодировке cp1251 (она же ANSI) // обратите внимание, не нужен main() { printf ("This is russian [аБвГдЕ] before cons1251()\n"); cons1251(); printf ("This is russian [аБвГдЕ] after cons1251()\n"); char str[1000], buf[1000]; printf ("Привет - введи часть от \"привет\"\n"); fflush(stdout); fgets(str,1000,stdin); str[strlen(str)-1] = 0; printf("Вы ввели: '%s'\n",str); if(strstr("привет",str)) printf("да, часть от 'привет'\n"); else printf("такого нет в слове 'привет'\n"); fflush(stdout); puts("ждем ввода to exit..."); fflush(stdout); fgets(str,1000,stdin); } Вызов fflush(stdout) при работе с консолью (tty) необязателен, однако для вывода в некоторых эмуляторах терминала (например в Emacs eshell) необходим. Это пример компиляции (Windows 7, Emacs eshell) окно в cp1251 поэтому вывод русского текста и до и после cons1251() одинаковый (и правильный). c:/Users/avp/src/cc/hashcode $ gcc -c cons1251.c c:/Users/avp/src/cc/hashcode $ gcc rustest.c cons1251.o -o rustest c:/Users/avp/src/cc/hashcode $ ./rustest This is russian [аБвГдЕ] before cons1251() This is russian [аБвГдЕ] after cons1251() Привет - введи часть от "привет" иве Вы ввели: 'иве' да, часть от 'привет' ждем ввода to exit... c:/Users/avp/src/cc/hashcode $ c:/Users/avp/src/cc/hashcode $ К сожалению для стандартного cmd-окошка Copy/Paste не работает, так что попробуйте сами. Для окна с PowerShell в Win 7 этот метод к сожалению не работает (в отличие от «геморройного» CharToOem/OemToChar). Надеюсь этот текст окажется кому-то полезным. UPDATE 2 (for @Rules) Исходный файл tt.cpp #include extern "C" void cons1251(void); main() { std::cout << "Привет, введите слово\n"; cons1251(); std::cout << "Привет, введите слово\n"; char str[100]; std::cin >> str; std::cout << "Вы ввели: " << str << std::endl; } c:/Documents and Settings/avp/src/hashcode $ g++ tt.cpp cons1251.o -o tt c:/Documents and Settings/avp/src/hashcode $ ./tt Привет, введите слово Привет, введите слово йцукен Вы ввели: йцукен c:/Documents and Settings/avp/src/hashcode $ Пример вывода из эмулятора терминала Emacs eshell. Поэтому первый «Привет...» тоже состоит из нормальных букв. В обычной консоли там «кракозябры», а дальше нормальная кириллица. Обращаю особое внимание. Перед запуском надо изменить шрифт в консоли на Lucida Console. Иначе будут кракозябры (но другие). Для замены шрифта кликаете правой кнопкой на надписи «Командная строка» окна консоли. В открывшемся меню выбираете «Свойства». В появившемся окне выбираете вкладку «Шрифт» и там выбираете «Lucida Console». Потом подтверждаете, что попросит. Если при подтверждении выбрать пункт «Изменить ярлык для запуска этого окна», то новые окна командной строки будут уже с нужным шрифтом. Вроде все.

Ответ 2



Можно сразу редактировать исходник в кодировке cp866, для этого нужен любой редактор, поддерживающий эту кодировку. Например, можно редактировать во встроенном редакторе far manager. В мейне вставляем вызовы двух функций: SetConsoleCP(1251); SetConsoleOutputCP(1251); и при первом запуске устанавливаем шрифт консоли на Lucida Console или Consolas.

Ответ 3



Вам необходимо сменить кодировку локали через функцию setLocale(): setlocale(LC_ALL,"Russian"). Более подробное описание: setlocale.

Ответ 4



Интересно, а почему бы просто не использовать русскую локаль(?): ... #include ... int main() { setlocale(LC_ALL,"Russian"); // русская локаль }

Ответ 5



Русский язык в исходном коде в Dev C++ К среде разработки и компилятору это не имеет никакого отношения. Этот вопрос достаточно распространён. Зачем задавать его лишний раз, если он легко гуглится? Вот некоторые ссылки: Как вывести в консоль русские буквы? Проблема с русским в Visual Studio 2005 (c++)

Комментариев нет:

Отправить комментарий