Как писать кириллический текст на консоли С++

Например, если я пишу:

cout << "Привет!" << endl; //it hello in Russian

В консоли это будет что-то вроде ╧ЁштхЄ!.

Хорошо, я знаю, что мы можем использовать:

setlocale(LC_ALL, "Russian");

Но после этого аргументы командной строки на русском языке не работают (если я запускаю свою программу через файл BAT):

StartProgram.bat

chcp 1251
MyProgram.exe -user=Олег -password=Пароль

Итак, после setlocale программа не может правильно прочитать русские аргументы.

Это происходит из-за того, что файл BAT в CP1251, но консоль находится в CP866.

Итак, возникает вопрос:

Как писать русский текст на консоли С++ и в то же время правильно читать аргументы командной строки.

Ответы

Ответ 2

Пробовали ли вы использовать wcout? Он похож на cout, но он принимает "широкие" символы, что должно допускать правильные кодировки в кодировке unicode.

Эта статья о локализации и еще, оба из MSDN могут быть полезны.

Ответ 3

Вы можете попробовать использовать следующие функции setlocale() и SetConsoleOutputCP()

setlocale(LC_ALL, "Russian");
SetConsoleOutputCP(866);

Ответ 4

Консоль установлена ​​в 1251 вместо 866:

 //Save As Windows 1251
    #include<stdio.h>
    #include<windows.h>
    int main(int argc, char **argv){ 
        SetConsoleOutputCP(1251);
        SetConsoleCP(1251);
        if(argc<2)return 0;
        else printf("Hello %s %s\n",argv[1],argv[2]);
    } 

Программа - аргумент .exe и результат:

D:\Debug > аргумент Олег пароль
Здравствуйте, Олег пароль

Ответ 5

Установили ли вы, что язык для программ, отличных от юникода, является русским, в разделе "Язык и региональные стандарты" на панели управления?

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

Если моя память не играет в трюки, когда я работал с некоторым кодом от японских разработчиков, именно этот шаг заставил консоль правильно отображать японский текст не Unicode (Shift-JIS-кодирование).

Ответ 6

WriteConsoleW может обрабатывать UNICODE, например. Кириллические буквы без проблем. Если вы не пропустите функции форматирования wcout, вы можете перенаправить стандартный буфер wcout и напечатать его с помощью WriteConsoleW.

Здесь показан полный пример

// save and redirect cout buffer
wostringstream  newCoutBuffer;
wstreambuf*     oldCoutBuffer = wcout.rdbuf(newCoutBuffer.rdbuf());    

// do your wcout stuff here
// do your wcout stuff here

DWORD dwWritten;
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), newCoutBuffer.str().c_str(),newCoutBuffer.tellp(),&dwWritten,NULL);  

// restore cout buffer
wcout.rdbuf(oldCoutBuffer);

Ответ 7

Наиболее правильным способом является использование wcout + std:: imbue.

Но следует знать, что в API-интерфейсе setlocale произошли некоторые изменения, которые произошли в Windows Vista/7. "Русская" языковая строка больше не распознается как "cp866", по крайней мере, в Visual С++ CRT.

Чтобы получить выход cp866, попробуйте использовать это вместо:

::setlocale( LC_ALL , "russian_russia.866" );

Ответ 8

Для меня это, похоже, решает проблему:

#include <fcntl.h>
#include <io.h>
#include <iostream>

using namespace std;

int main(void) {
    _setmode(_fileno(stdout), _O_U16TEXT);
    wcout << L"Огњен" << endl;
    return 0;
}