从 std::wcin 中检索有效的系统编码字符串

Retrieving valid system encoded strings from std::wcin

提问人:teviroff 提问时间:8/3/2023 更新时间:8/4/2023 访问量:42

问:

最近,我遇到了从用户那里读取非 ASCII 字符的必要条件。我怀疑这在处理文件时相对容易,但我并没有真正了解它。我想同时支持文件输入和 stdin。这就是问题开始的地方。

首先,我使用的是 Windows,我也知道从控制台读取取决于平台,因为 Windows 使用 UTF-16 而 UNIX 使用 UTF-8,但我认为如果我迁移到 UNIX,可能会出现同样的问题。因此,这是我用来捕获宽控制台输入的代码片段:

#include <iostream>
#include <string>
#include <locale>

template<class T> toBytes(T obj) { ... }

int main() {
    std::setlocale(LC_ALL, "en_US");
    std::wstring ws;
    std::getline(std::wcin, ws);
    for (auto c : ws) {
        std::wcout << toBytes(c) << L' ' << L'(' << (int)c << L", \'" << c << L"\')";
    }
}

但。。。这并没有真正奏效,这是输出:

Output for non-transformable char

对于某些字符,它能够将它们转换为 ASCII:

Output for transformable char

所以,请帮忙 😄

C++ IO 字符编码 控制台应用程序

评论


答:

0赞 teviroff 8/4/2023 #1

我想我找到了这个问题的答案。实际上,winapi(确切地说是“io.h”和“fcntl.h”)中有一个函数用于更改文件描述符的编码。因此,在 main 函数的开头放置以下两行会有所帮助:

_setmode(_fileno(stdin), _O_U16TEXT);
_setmode(_fileno(stdout), _O_U16TEXT);

但有一点需要注意,代理项对似乎根本无法在控制台中工作,它们已正确编码,但不幸的是没有显示。