我可以使用 wstring 来读取、解析和发出 utf-8 吗?

Posted

技术标签:

【中文标题】我可以使用 wstring 来读取、解析和发出 utf-8 吗?【英文标题】:Can I use wstring to read, parse, and emit utf-8? 【发布时间】:2015-12-13 10:16:49 【问题描述】:

我正在编写一个程序,它从单个 .csv 文件中读取翻译(EN、JP、SP),对其进行解析,然后将其发送到另一个文件。每个字符 8 位是不够的,但是使用 wstring 和 wchar_t 只能设法打乱我从文件中读取的文本。老实说,我真的不知道从哪里开始,研究这个话题主要是发现我对这个话题有强烈的看法,而有用的信息很少。

wstring 可以做 utf-8 吗? utf-8 甚至是我应该关心的事情吗?

如果我有一个包含多种语言字符的 u8"string" 或 L"string",我将如何仅使用 C 标准 IO 库将其写入文件?

(我非常决心只使用标准 IO 库来完成这项工作,即使这意味着一次写入一个字节)

【问题讨论】:

根据你解析字符串的方式,你可以使用std::string来包含多字节数据,有点像这样:***.com/a/29782183/3807729 【参考方案1】:

wstring 可以做 utf-8 吗?

C++ 具有能够在 wstring 和 UTF-8 字符串之间转换的标准函数 (wstring_convert)。 C 和 C++ 中也有标准函数(wcstombsmbstowcs),如果您的系统具有适当的语言环境,它们可能能够对 C-wstrings 执行相同的操作。大多数 POSIX-is 系统都可以,而基于 Windows 的系统通常不会(它们为此提供了非标准工具)。这就是 wstring 和 UTF-8 之间的所有关系。

utf-8 是我应该关心的吗?

这取决于。如果你生活在 1980 年,或者不做任何编程,那么可能不会。如果你不做任何字符级的处理,而只打乱整个字符串,你也应该没问题。只需使用基于char 的字符串,不用担心任何花哨的字符。这一切都应该或多或少自动运行。

如果您确实需要字符级别的内容(子字符串、搜索等),您可能确实需要了解 UTF-8。使用 wchar_t 或 char32_t 进行所有内部处理并在 I/O 时从或转换为 UTF-8 可能是明智的。 (我只想说“使用 wchar_t”,但可惜的是,在 Windows 上 wchar_t 已损坏。您可能仍然可以摆脱它,但没有承诺。)

如果我有一个包含多种语言字符的 u8"string" 或 L"string",我将如何仅使用 C 标准 IO 库将其写入文件?

你不能在 C 中对 u8"string" 做太多事情。在 C++ 中,它们是普通的基于 char 的字符串,可以写成任何其他字符串,并且做正确的事情。 (您可能需要在 Windows 上跳过一些障碍,请参阅 _setmode 和 _O_U8TEXT 文档)。然而,Thia 是次要的。您几乎不需要需要在字符串文字中有任何花哨的字符。所有面向用户的字符串都应该从文件中加载。

使用基于 wchar_t 的字符串,您可能会也可能无法直接输出 UTF-8,具体取决于您的操作系统和编译器。您始终可以转换为 UTF-8 并输出。

如果你愿意使用第三方库,可以考虑使用http://utfcpp.sourceforge.net/

另请阅读: http://utf8everywhere.org http://www.joelonsoftware.com/articles/Unicode.html

【讨论】:

由于Windows上的wchar_t只有16位,所以wstring的编码是UTF-16,也是和UTF-8一样的变长编码。所以仍然存在 wstrings 包含代理对的风险,大多数字符串处理函数都不支持。最安全的做法是将所有内容都转换为 UTF-32,使用 UTF-32 进行字符串处理,然后再转换回 UTF-8 用于 I/O。但在许多情况下,您仍然可以使用 UTF-16,因为大多数字符都适合单个 UTF-16 字符。请注意它们可能不适合。【参考方案2】:

从 wstring 转换为 utf8:

#include <string>
#include <codecvt>

std::wstring wstring_convert_from_char( const char *str )

    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
    return converter.from_bytes( str );


std::string string_convert_from_wchar( const wchar_t *str )

    std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
    return converter.to_bytes( str );

【讨论】:

以上是关于我可以使用 wstring 来读取、解析和发出 utf-8 吗?的主要内容,如果未能解决你的问题,请参考以下文章

未解析的外部使用 fmt::format 返回 std::wstring

将 wstring 转换为 UTF-8 编码的字符串

C++ 代码优化

POST 请求使用 wstring 类型截断并使用字符串格式良好

如何使用 yaml-cpp 发出和解析原始二进制数据

从 std::string 和 std::wstring 获取 char 整数值