在 C++17 / C++20 中从 wstring 转换为 u16string 并返回(标准符合)
Posted
技术标签:
【中文标题】在 C++17 / C++20 中从 wstring 转换为 u16string 并返回(标准符合)【英文标题】:Conversion from wstring to u16string and back (standard conform) in C++17 / C++20 【发布时间】:2020-08-03 00:22:36 【问题描述】:我的主要平台是 Windows,这就是我在内部使用 UTF-16(主要是 BMP 字符串)的原因。 我想为这些字符串使用控制台输出。
不幸的是,没有std::u16cout
或std::u8cout
,所以我需要使用std::wcout
。因此我必须将我的 u16strings 转换为 wstrings - 最好(也是最简单)的方法是什么?
在 Windows 上,我知道 wstring 指向 UTF16 数据,因此我可以创建一个使用相同数据的简单 std::u16string_view(无转换)。 但在 Linux 上 wstring 通常是 UTF32 ...... 有没有办法在没有宏且没有假设 sizeof(wchar_t) == 2 => utf16 的情况下做到这一点?
【问题讨论】:
如果您使用的不是 Windows,您不应该使用std::cout
和std::string
,而不是std::wcout
和std::wstring
?也就是说,不应该转换为在非 Windows 平台上普遍存在的 UTF-8 吗?
他可能正在处理由 Windows 应用程序生成的数据,以及为 Linux 服务器上的 Windows 应用程序或类似的东西生成的数据。编辑:啊,他正在使用 BMP 字符串。有你的理由
这能回答你的问题吗? how can I convert wstring to u16string?
【参考方案1】:
C++20 标准中没有任何内容可以将wchar_t
转换为char32_t
并返回。毕竟,wchar_t
是 supposed to be 大到足以包含任何支持的代码点。
确实,U+FFFF 以上的所有 Unicode 都支持,wchar_t
是 32 位的,除了 Windows(和 Java,但这无关紧要)。所以是的,即使在今天以可移植的方式使用 Unicode 也是有问题的,sizeof(wchar_t)==2
或 #ifdef _WIN32
听起来都是合法的解决方法。
话虽如此,wcout
仍然可以在所有平台上与wchar_t
无缝协作,无论底层编码如何。
只有当您剪切 wstrings或使用单个代码点并且您想要支持基本平面之外的代码点,然后您需要考虑代理对(这仍然很简单,0xD800–0xDBFF = 第一对,0xDC00–0xDFFF = 第二对,不要介于两者之间)。
【讨论】:
我认为同样重要的是要注意char32_t
只代表一个代码点而不是字素。如果您需要使用需要专门库的实际渲染字素。这很复杂......只是一点点。
是的,Unicode 也有 c̮oͣm̥bͮi̪n̆ìnͨǵ čh̎a͏r̷a͍c̘t́èr̗sͥ...
我现在用你的解决方法做到了......不太好,但它有效:-)以上是关于在 C++17 / C++20 中从 wstring 转换为 u16string 并返回(标准符合)的主要内容,如果未能解决你的问题,请参考以下文章
在 C/C+ 中从 16 位线性 PCM 音频转换为 32 位浮点的最佳方法?
在目标 c 中从 UIWebView.scrollView 写入 PDF 文件
在 C 中从用户那里获得 *secure* 输入的最佳方式是啥?