【问题标题】:Read file with unknown character type读取未知字符类型的文件
【发布时间】:2020-12-27 19:10:48
【问题描述】:

我需要从可能包含任何类型字符(charchar8_twchar_t 等)的文件中读取文本。如何确定使用哪种类型的字符并根据该类型创建basic_ifstream<char_type> 的实例?

【问题讨论】:

    标签: c++ file character-encoding


    【解决方案1】:

    所以我猜你想自动检测未知文本文件的编码。

    这是不可能以 100% 可靠的方式做到的。但是,我的经验表明,在大多数实际情况下,您都可以实现非常高的可靠性(> 99.99%)。文件越大,猜测其编码最可靠:通常十分之几字节就足以对猜测充满信心。

    有效的 Unicode 代码点是包含从 U+1 到 U+10FFFF 的值,不包括代理范围 U+D800 到 U+DFFF。代码点 U+0 实际上是有效的,但排除它会大大减少误报猜测的数量(NUL 字节不应出现在任何实际的文本文件中)。为了更好地猜测,我们可以排除一些更罕见的控制字符。

    这是我建议的算法:

    • 如果文件以有效的 BOM(UTF-8、UTF-16BE/LE、UTF-32BE/LE)开头,请相信该 BOM。
    • 如果文件仅包含 ASCII 字符(非空字节 char)。
    • 如果文件是valid UTF-8,则假定它是UTF-8(使用char8_t,但char 也可以)。请注意,ASCII 是 UTF-8 的子集,因此可以绕过之前的检查。
    • 如果文件是有效的 UTF-32(检查小端和大端版本),则采用 UTF-32(char32_t,在 Linux 或 macOS 上也可能是 wchar_t)。如果需要,交换字节。
    • 如果文件是有效的 UTF-16(检查小端和大端版本),包括对代理对的限制,并且偶数字节或奇数字节之间的相关性高于所有字节之间的相关性,则假定 UTF-16 (@ 987654327@,在 Windows 上也可能是 wchar_t)。如果需要,交换字节。
    • 否则,文件可能不是某种 Unicode 编码,并且可能使用旧代码页。祝你好运自动检测哪一个。到目前为止,更常见的是 8859-1(Latin-1),使用 char。也可能是一些原始的二进制数据。

    【讨论】:

      【解决方案2】:

      不可能确定。你必须被告知字符类型是什么。文本文件通常以 Byte-Order-Mark 开头以提示您,但即使这样也不是万无一失的。

      您可以对文件内容做出合理的猜测,例如,如果您“知道”其中大部分是 ASCII 范围的文本,那么应该很容易判断文件是否是充满charwchar_t 字符。即使这也依赖于假设,不应被视为万无一失。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-23
        • 1970-01-01
        相关资源
        最近更新 更多