有没有正确的方法以 UTF-8 编码从控制台接收输入?

Rau*_*una 5 c++ windows utf-8 character-encoding visual-studio

当从 Windows 中获取输入时std::cin,输入显然始终采用 windows-1252 编码(在我的情况下是主机的默认值),尽管进行了所有配置,但这显然只影响输出。有没有正确的方法以 UTF-8 编码捕获 Windows 中的输入?

\n

例如,让我们看看这个程序:

\n
#include <iostream>\n\nint main(int argc, char* argv[])\n{\n    std::cin.imbue(locale("es_ES.UTF-8"));\n    std::cout.imbue(locale("es_ES.UTF-8"));\n\n    std::cout << "\xc3\xb1e\xc3\xb1e\xc3\xb1e> ";\n    std::string in; \n    std::getline( std::cin, in ); \n    std::cout << in; \n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我在具有西班牙语语言环境的 Windows 计算机中使用 Visual Studio 2022 编译了它。源代码采用 UTF-8 格式。执行生成的程序时(Windows powershell 会话,执行后将chcp 65001默认编码设置为 UTF-8),我看到以下内容:

\n
PS C:\\> .\\test_program.exe\n\xc3\xb1e\xc3\xb1e\xc3\xb1e> \xc3\xb1e\xc3\xb1e\xc3\xb1e\n e e e\n
Run Code Online (Sandbox Code Playgroud)\n

第一个“\xc3\xb1e\xc3\xb1e\xc3\xb1e”是正确的:它在输出控制台正确显示“\xc3\xb1”字符。到目前为止,一切都很好。用户输入正确地回显到控制台:另一个优点。但!当它转向将编码字符串发送回输出时,“\xc3\xb1”字符被空白替换。

\n

调试此程序时,我发现变量“in”已捕获非 utf-8 编码的输入:对于“\xc3\xb1”,它仅使用一个字符,而在 utf-8 中,该字符必须消耗两个。结论是输入对chcp命令没有影响。我做错了什么吗?

\n

更新

\n

有人让我看看更改为 wcout/wcin 时会发生什么:

\n
std::wcout << u"\xc3\xb1e\xc3\xb1e\xc3\xb1e> ";\nstd::wstring in;\nstd::getline(std::wcin, in);\nstd::wcout << in;\n
Run Code Online (Sandbox Code Playgroud)\n

行为:

\n
PS C:\\> .\\test.exe\n0,000,7FF,6D1,B76,E30\xc3\xb1e\xc3\xb1e\xc3\xb1e\n e e e\n
Run Code Online (Sandbox Code Playgroud)\n

其他尝试(将字符串设置为 L"\xc3\xb1e\xc3\xb1e\xc3\xb1e"):

\n
\xc3\x83\xc2\xb1e\xc3\x83\xc2\xb1e\xc3\x83\xc2\xb1e> \xc3\xb1e\xc3\xb1e\xc3\xb1e\n e e e\n
Run Code Online (Sandbox Code Playgroud)\n

保持原样:

\n
std::wcout << "\xc3\xb1e\xc3\xb1e\xc3\xb1e> ";\n
Run Code Online (Sandbox Code Playgroud)\n

结果是:

\n
eee>\n
Run Code Online (Sandbox Code Playgroud)\n

Rau*_*una 0

这是迄今为止我找到的最接近的解决方案:

\n
int main(int argc, char* argv[])\n{\n    _setmode(_fileno(stdout), _O_WTEXT);\n    _setmode(_fileno(stdin), _O_WTEXT);\n\n    std::wcout << L"\xc3\xb1e\xc3\xb1e\xc3\xb1e";\n    std::wstring in;\n    std::getline(std::wcin, in);\n    std::wcout << in;\n\n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这里描述的解决方案朝着正确的方向发展。问题:stdin 和 stdout 应该具有相同的配置,因为控制台的 echo 重写了输入。问题是用 \\uXXXX 代码编写字符串......我猜测如何克服这个问题或使用#define\ 来克服和澄清文本文字

\n