C++:如何将 std::string 的内容写入 UTF-8 编码文件?

Posted

技术标签:

【中文标题】C++:如何将 std::string 的内容写入 UTF-8 编码文件?【英文标题】:C++: How do I write the contents of std::string to a UTF-8 encoded file? 【发布时间】:2021-07-22 21:13:57 【问题描述】:

我在 Windows 上使用 C++。我在 std::string 中有一些数据,我想用 UTF-8 编码写入文件。我该怎么做?

【问题讨论】:

你试过什么?你所需要的基本上是file << string; 您需要在文件开头添加 BOM (en.wikipedia.org/wiki/Byte_order_mark) 吗? 可以肯定的是,对于 UTF-8 ofstream,如果这是您的要求,您可以使用 std::basic_ofstream<char8_t> 我试过文件 @VikasKakkar NotePad 的编码是它用来解释文件中包含的数据(并显示它)的编码。它没有说明使用什么编码来生成文件。基本上,编码只是一种约定(在语义层面上),但实际上,您的文件只包含字节^^ 【参考方案1】:

这类似于How do I write a UTF-8 encoded string to a file in windows, in C++。

请注意,跨平台写入文件是不同的(在 Windows 中,您有 CreateFile、WriteFile、ReadFile、CloseHandle,它们不仅限于文件,还可以对设备驱动程序执行操作),在 linux 中,您有不同的集合功能。最好检查您打算使用的平台(在您的情况下是 Windows)。

【讨论】:

嗯,是的,有一些特定于平台的文件管理方法。但是 C++ 标准库中有用于管理文件的代码,这些代码掩盖了这些差异,因此您不必为不同的平台编写不同的代码。【参考方案2】:

我在 std::string 中有一些数据,我想用 UTF-8 编码写入文件。我该怎么做?

如果字符串包含 UTF-8 编码的文本,则只需写入数据。例如,您可以使用std::ofstream

如果字符串中不包含 UTF-8 格式的数据,那么在写入之前,必须先从数据当前所在的编码进行转换。C++ 标准库没有通用的字符编码转换函数(忽略少数已弃用)。通常没有保证检测当前编码的方法。你应该事先知道。


但是当我在记事本中检查创建文件的编码时,它是 ANSI 而不是 UTF-8

就像我在上一节中提到的关于检测字符串的源编码,没有保证的方法可以做到这一点。记事本也没有这种超能力。它可能使用简单的规则来猜测编码。有时会猜错。

UTF-8 对 7 位 ASCII 编码中的字符具有与 ASCII 本身相同的表示(我猜记事本通过名称“ANSI”调用 ASCII)。如果您的字符串仅包含这些字符,则字符串的 UTF-8 编码与 ASCII 无法区分。在这种情况下,记事本很可能会猜错(尽管从技术上讲,猜测也是正确的,因为在这种情况下,UTF-8 也可能是 ASCII)。

【讨论】:

"C++ 标准库没有通用的字符编码转换函数"——其实也有一些,但不是很好。在这里实际有用的那个 - std::wstring_convertstd::codecvt_utf8/_utf16 - 已被弃用,目前还没有替代品。 @RemyLebeau 为什么std::codecvt_utf8/_utf16std::wstring_convert 在将存储在std::string 中的一些窄编码转换为另一种窄编码(特别是UTF-8)时很有用。它们都不是 UTF-16。 窄到窄的转换需要到Unicode/UTF-16的中间转换,所以narrow->Unicode/UTF16->narrow/UTF8。 wstring_convert/`codecvt 至少对第二步很有用。

以上是关于C++:如何将 std::string 的内容写入 UTF-8 编码文件?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 将 std::string 复制到没有空终止的 char 数组

C++:指向 std::string 转换的 char 指针是不是复制内容?

如何在 C++ 中将整个文件读入 std::string?

如何将字符串保存到 C++ 中类的 string* 成员?

如何最好地将 std::vector < std::string > 容器写入 HDF5 数据集?

C++ .NET 将 System::String 转换为 std::string