【问题标题】:How to convert a UTF-8 string to the encoding of a stream如何将 UTF-8 字符串转换为流的编码
【发布时间】:2018-05-24 02:40:15
【问题描述】:

想象一下,我决定在我的 C++11 程序中使用 use UTF-8 everywhere internally,所以我有一个 std::string,其中包含以 UTF-8 编码的文本。我现在想做一些该文本的 IO。例如,将其写入std::cout。虽然我在内部使用了 UTF-8,但我不能假设程序用户和操作环境也如此强制使用 UTF-8。出于好的或坏的原因,我应该通过std::cout 发送的文本的字符编码可能不是UTF-8。 My program must perform a conversion,获取我的 UTF-8 编码文本并将其转换为 std::cout 期望的编码。如何找出该输出流上的编码,然后进行字符编码?

查看标准 C++ 流的声明,看起来我可以使用 std::io_base::get_loc 获取输出流的“语言环境”,然后获取流的 std::codecvt“代码转换方面”。但是我应该获得哪个方面?以及如何实际使用该方面将 UTF-8 转换为输出编码?

如果标准库的那些设施不能完成任务,我还有什么其他选择?

【问题讨论】:

  • 在哪个操作系统、终端、版本等上
  • 在 C++ 中没有标准的方法可以做到这一点。如果您的用户不喜欢 UTF-8,那么抛弃它们并迎合更好的用户在经济上是可行的。
  • @Surt 我想写可移植的代码。当然,语言环境和语言环境方面的全部意义在于,因此您不需要知道这些细节:语言环境和方面的实现会小心。
  • 语言环境和语言环境方面以及围绕它们的一大堆 C++ API 是彻底失败的。目前没有可移植的 C++ 程序利用语言环境并支持 Unicode。什么都写不出来。
  • 您的其他选择是:(1) 第三方库,如 icu 或 iconv (2) 知道并依赖于在流行的实现中宽字符串实际上是 utf16 或 ucs4 编码的事实

标签: c++ c++11 utf-8 iostream


【解决方案1】:

如何找出该输出流的编码

你没有。

任何不是你自己的输出流(无论是coutcerr、文件流还是其他)的接收者的期望不是你可以确定的。 “标准输出”的概念并没有与“编码”的相关概念捆绑在一起。编码期望是隐式的,而不是显式的。

是的,流具有语言环境方面。但这纯粹是您在说“我想以这种方式编码输出”。这没有说明流另一端的消费者的需求。这只是一种让您根据您认为接收者想要的方式进行转换的方式。

C++ 没有办法查询接收者的期望。如果没有这些知识,ICU 或 iconv 或其他任何东西都对您没有帮助。

这通常是使用特定于平台的代码来完成的。在您的 Windows 版本中,您可以输出以 UTF-16 编码的 wchar_ts,或者设置代码页并使用构面进行转换。在 Linux 上,您通常可以假设控制台将接受 UTF-8。以此类推。

但没有简单的“这样做,它会起作用”的机制。

【讨论】:

  • 我们无法确定接收者的期望,因为我们无法读懂人们的想法,但系统默认内置了接收者应该得到的规范语言环境(在 C 和 C++ 中名称为 "")。
  • @n.m.:但这并不能真正解决 OP 的问题。
  • 不,它没有。我只是反对你的回答。它指出问题无法解决,这是正确的,但您引用了所有错误的原因。
  • 好的,所以让我们假设我可以确定要使用的编码(可能使用系统相关的方法)。我的问题还问,我下一步该怎么做?如果std::cout 有一个正确的std::locale 对象,我该如何使用它来将UTF-8 字符串转换为该语言环境的编码?
  • 带着沮丧、困惑和愤怒的情绪,我了解到support for Unicode in standard C++ is terrible
猜你喜欢
  • 1970-01-01
  • 2016-10-01
  • 2011-12-08
  • 2011-05-20
  • 2014-05-02
  • 2012-06-30
  • 1970-01-01
  • 2011-08-16
相关资源
最近更新 更多