【问题标题】:Read UTF8 files on windows and linux through c++通过c++在windows和linux上读取UTF8文件
【发布时间】:2012-04-14 08:33:14
【问题描述】:

我有一些使用 UTF-8 编码的文本文件。有没有办法使用 c++ 流类(例如 wifstream)来读取它们?

我见过一些外部参考,比如 boost 和一些 codeproject 代码 sn-ps。但是,我不想仅仅为了这个目的而使用它。

在 linux 上,它通过调用 imbue(std::locale("en_US")) 以某种方式工作,但在 Windows 上却不行。我认为问题在于窗口假定 wifstream 是 UTF-16 编码流。我不能以某种方式使用 wifstream 类指定 unicode 编码,以便它使用 UTF-8 而不是 UTF-16?

【问题讨论】:

  • 你用它们做什么?如果您随后将生成的缓冲区视为 UTF-8,则始终可以使用 ifstream 读取 UTF-8 文件。由于wchar_t 在 Windows 和 Linux 中的大小不同,“宽”流往往更不便携。
  • 我不会把它作为一个完整的缓冲区来阅读。假设我使用提取运算符并逐字符读取流,会发生什么?它会正确读取字符吗?我猜不是。

标签: c++ windows linux utf-8


【解决方案1】:

您可以正常在 Windows 上完美读取 utf8 文件 - 唯一的问题是当您想对它们做一些事情时。

几乎所有 Windows API 调用都使用 UTF16 或 MBCS,每当您将 UTF8-MBCS 传递给 Windows API 时,您都需要对其进行转换 - 请参阅 Converting C-Strings from Local Encoding to UTF8

【讨论】:

    【解决方案2】:

    除了从文件中正常读取字节,并将它们作为 UTF-8 处理(例如,不将它们传递给任何需要语言环境编码的字符串,只传递给需要 UTF-8 的东西),Windows 还有另一个以 UTF-8 读取的方式。

    您可以在文件描述符上设置“UTF-8”模式,然后在该文件描述符上使用宽字符输入和输出,Microsoft 的 C 运行时将处理宽字符与 UTF-8 编码字节流之间的转换:

    #include <fcntl.h>
    #include <io.h>
    #include <stdio.h>
    
    int main(void) {
      _setmode(_fileno(stdout), _O_U8TEXT);
      wprintf(L"\x043a\x043e\x0448\x043a\x0430 \x65e5\x672c\x56fd\n");
    }
    

    如果您运行上述程序并将输出重定向到一个文件,您将获得一个 UTF-8 编码的文件。

    在文件描述符上设置其中一种 Unicode 模式会对控制台产生额外的影响,即宽字符输出实际上可以在控制台上工作。我不确定微软为什么选择“损坏”作为默认设置,但至少有一种方法可以启用“未损坏”模式。

    【讨论】:

    • c++呢?我想为我的文件 io 使用 wifstream 类。
    • @Aarkan 如果启用了其中一种 Unicode 模式,那么您可以在其上使用任何标准 c 和 c++ wchar_t IO 例程,包括 wifstream 方法。诀窍是从流中获取文件描述符,以便首先设置模式。
    猜你喜欢
    • 2013-09-23
    • 2011-11-27
    • 2019-08-27
    • 2011-06-24
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    相关资源
    最近更新 更多