如何在C++的用户首选区域设置中正确显示字符串?

How to correctly display strings in user preferred locale in C++?

提问人:Sourav Kannantha B 提问时间:1/28/2023 最后编辑:Alan BirtlesSourav Kannantha B 更新时间:1/30/2023 访问量:79

问:

我在另一个问题中发布了这段代码:

auto operator<<(std::ostream& out, const std::u8string_view str) -> std::ostream& {
    std::locale::global(std::locale{".utf8"});
    auto& ret = out << std::string_view{std::bit_cast<const char*>(str.data()), str.size()};
    std::locale::global(std::locale{""});
    return ret;
}

我打算在打印前转换为用户首选的区域设置。但是在对那篇帖子的回答中,@Chronial指出我错误地使用了语言环境。u8stringglobal

我认为外流会解释编码中的数据,并在写入时将其转换为“d”编码。因此,由于我输入的数据在其中,并且我想在用户喜欢的区域设置中显示它,因此我更改了上面的代码并且没有触及它。globalimbueutf8globalimbue

例如:如果我的终端使用的是 EBCDIC,并且我的应用程序中有 ASCII 字符串,那么正确显示它们的正确过程是什么?直接显示它们会产生胡言乱语,AFAIK。

我的想法是,如果我设置为 ASCII 和 EBCDIC,这将使流将数据解释为 ASCII 并在打印前将其转换为 EBCDICglobalimbue

以上从ASCII转换为EBCDIC的场景仅以此为例。我一直在寻找一种通用解决方案,而不仅仅是 ASCIIEBCDIC 的情况。

C++ 字符串 区域设置 IOSTREAM

评论

0赞 KamilCuk 1/28/2023
我在 C++ 语言环境中很糟糕,但在 C 中,我会将语言环境设置为 ASCII,将字符串转换为宽字符,将语言环境设置为 EBCDIC,然后只需 printf(“%Ls” 宽字符串。 即宽字符是所有语言环境之间的桥梁,设置语言环境设置从字符串到宽字符的转换方法。If my terminal is using ebcdic and I have ascii strings
0赞 Ivan Venkov 1/28/2023
如果可能,您可以使用__a2e_s。在我看来,它完全符合您的要求。
0赞 Sourav Kannantha B 1/28/2023
@IvanVenkov 对不起,但我正在寻找一个更通用的解决方案,而不仅仅是.我更新了问题。__a2e_s()

答:

0赞 Chronial 1/30/2023 #1

C++ 标准库并非真正旨在帮助您解决此方案。您要么必须自己处理重新编码,要么使用宽字符流。然后,您将字符串解码为宽字符串,将它们写入流,然后流将使用它所填充的区域设置/编码来重新编码字符串。

但是,您编写的应用程序是否确实对您很重要?对于大多数应用程序来说,只写 UTF8 应该没问题,因为这是所有现代终端都应该配置的。

评论

0赞 Sourav Kannantha B 1/30/2023
设置使流将字符串转换为该编码,对吗?那么,在这种情况下,它假设字符串在哪种编码中?或者,它根本不重新编码字符串吗?imbue
0赞 Sourav Kannantha B 1/30/2023
我不想将任何内容转换为非 UTF-8。但我真的不明白 are 和 locales 是什么意思。我以为是内存的字符串编码,是终端的字符串编码。globalimbueglobalimbue