在 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::u16coutstd::u8cout,所以我需要使用std::wcout。因此我必须将我的 u16strings 转换为 wstrings - 最好(也是最简单)的方法是什么?

在 Windows 上,我知道 wstring 指向 UTF16 数据,因此我可以创建一个使用相同数据的简单 std::u16string_view(无转换)。 但在 Linux 上 wstring 通常是 UTF32 ...... 有没有办法在没有宏且没有假设 sizeof(wchar_t) == 2 => utf16 的情况下做到这一点?

【问题讨论】:

如果您使用的不是 Windows,您不应该使用std::coutstd::string,而不是std::wcoutstd::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* 输入的最佳方式是啥?

在 Windows 环境中从 C 或 C++ 访问 COM 接口

从 DLL 返回 std::wstring 是不是安全?

我的C/C++语言学习进阶之旅收集关于MODERN C++ 11/14/17/20/23 的一些资料