如何在 C++ 控制台中编写西里尔文文本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2261496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:45:52  来源:igfitidea点击:

How to write Cyrillic text in C++ console

c++encodingcharacter-encoding

提问by VextoR

For example, if I write:

例如,如果我写:

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

In the console it would be something like ╧Ёштх?!.

在控制台中,它将类似于╧Ёштх?!.

OK, I know that we can use:

好的,我知道我们可以使用:

setlocale(LC_ALL, "Russian");

But after that, command line arguments in Russian do not work (if I start my program through a BAT file):

但在那之后,俄语中的命令行参数不起作用(如果我通过 BAT 文件启动我的程序):

StartProgram.bat

启动程序.bat

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

So, after setlocalethe program can't read Russian arguments properly.

因此,在setlocale程序无法正确读取俄语参数之后。

This happens because the BAT file in CP1251, but the console is in CP866.

出现这种情况是因为 BAT 文件在 CP1251 中,而控制台在 CP866 中。

So, there is a question:

那么,有一个问题:

How can I write Russian text in the C++ console and at the same time have Russian command line arguments read properly.

如何在 C++ 控制台中编写俄语文本,同时正确读取俄语命令行参数。

采纳答案by Nemanja Trifunovic

See this entry from Michael Kaplan's blog:

请参阅 Michael Kaplan 博客中的此条目:

http://www.siao2.com/2008/03/18/8306597.aspx

http://www.siao2.com/2008/03/18/8306597.aspx

回答by e.James

Have you tried using wcout? It is similar to cout, but it accepts "wide" characters, which should permit the proper unicode encodings.

你试过使用wcout吗?它类似于cout,但它接受“宽”字符,这应该允许正确的 unicode 编码。

This article about localization, and another, both from MSDN may be of use.

条有关本地化,和另一个,无论是从MSDN可能是使用的。

回答by vladasimovic

Console set to be in 1251 instead of in 866:

控制台设置为 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]);
    } 

Program is argument.exe and result:

程序是argument.exe,结果:

D:\Debug>argument Олег Пароль
Hello Олег Пароль

D:\Debug>argument Олег Пароль
你好 Олег Пароль

回答by Ог?ен Шоба?и?

For me this seems to resolve the problem:

对我来说,这似乎解决了这个问题:

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

using namespace std;

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

回答by Ог?ен Шоба?и?

Have you set the language for non-unicode programs to be Russian, in the Regional and Language Options section of the Control Panel?

您是否在控制面板的区域和语言选项部分将非 Unicode 程序的语言设置为俄语?

(I have no idea what the usual setup for Russian-speaking programmers might be; I just wonder whether it is common to set this to some kind of English to avoid confusing overly-parochial tools.)

(我不知道讲俄语的程序员通常的设置是什么;我只是想知道将其设置为某种英语以避免混淆过于狭隘的工具是否很常见。)

Unless my memory is playing tricks, when I was working with some code from Japanese developers it was this step that got the console displaying non-Unicode Japanese text (Shift-JIS encoding) properly.

除非我的记忆在耍花招,否则当我使用日本开发人员的一些代码时,正是这一步让控制台正确显示了非 Unicode 日语文本(Shift-JIS 编码)。

回答by kruk

You can try using the following functions setlocale()and SetConsoleOutputCP()

您可以尝试使用以下功能setlocale()SetConsoleOutputCP()

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

回答by seizu

WriteConsoleWcan handle UNICODE e.g. Cyrillic letters without problems. If you won't miss the formatting features of wcout, you can redirect the standard wcoutstream buffer and print it with WriteConsoleW.

WriteConsoleW可以毫无问题地处理 UNICODE 例如西里尔字母。如果您不会错过wcout的格式化功能,您可以重定向标准wcout流缓冲区并使用WriteConsoleW打印它。

A full example is shown here

这里显示了一个完整的例子

// 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);

回答by Yury Rumega

The most correct way is using wcout + std::imbue.

最正确的方法是使用 wcout + std::imbue。

But one should know that there was some changes in setlocale API which happened in Windows Vista/7. "Russian" locale string isn't recognized as "cp866" anymore, at least in Visual C++ CRT.

但是应该知道 Windows Vista/7 中 setlocale API 发生了一些变化。“Russian”语言环境字符串不再被识别为“cp866”,至少在 Visual C++ CRT 中是这样。

To get cp866 output, try use this instead:

要获得 cp866 输出,请尝试使用以下命令:

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