【问题标题】:Detecting Unicode in files in Windows 10在 Windows 10 中检测文件中的 Unicode
【发布时间】:2021-05-02 02:55:21
【问题描述】:

现在 Windows 10 记事本不需要 unicode 文件具有 BOM 标头,并且默认情况下不对标头进行编码。这确实破坏了检查标头以确定文件中的 Unicode 的现有代码。我现在如何在 C++ 中判断文件是否为 unicode? 来源:https://www.bleepingcomputer.com/news/microsoft/windows-10-notepad-is-getting-better-utf-8-encoding-support/

我们要确定Unicode的代码:

int IsUnicode(const BYTE p2bytes[3])
{
        if( p2bytes[0]==0xEF && p2bytes[1]==0xBB p2bytes[2]==0xBF) 
            return 1; // UTF-8
        if( p2bytes[0]==0xFE && p2bytes[1]==0xFF)
            return 2;  // UTF-16 (BE)
        if( p2bytes[0]==0xFF && p2bytes[1]==0xFE) 
            return 3; // UTF-16 (LE)
            
        return 0;
}

如果这么痛苦,为什么没有一个典型的函数来确定编码?

【问题讨论】:

  • 这不太可能。您可以通过查看内容猜测并尝试将其解码为例如UTF-8 或类似的。如果失败,则回退到操作系统的当前设置。
  • “现在 Windows 10 不需要 unicode 文件具有 BOM 标头。” - 此声明的来源是什么?什么时候需要文件中的任何内容?
  • 这里只有启发式可以提供帮助。如果每第二个字节的大部分为空,那么该文件很可能是一个 unicode 文件
  • notepad.exe 行为的变化与整个 Windows 10 的行为变化相差甚远......
  • @dxiv "看看IsTextUnicode" - 这是记事本使用的,can report wrong results 正因为如此。

标签: c++ windows c++11 unicode


【解决方案1】:

现在 Windows 10 不需要 unicode 文件具有 BOM 标头。

Windows 从来没有这个要求。每个程序都可以随意读取文本文件。

也许很有趣:BOM may not be desirable for UTF-8,因为它破坏了 ASCII 兼容性。

这确实破坏了检查标头以确定文件中的 Unicode 的现有代码。

这是一个误解。其他代码可能比 Windows 的记事本支持 Unicode 的时间更长。

现在如何在 C++ 中判断文件是否为 unicode?​​p>

通常您会检查是否存在 BOM,然后当然会使用该信息。

接下来,您可以尝试使用所有可能的编码读取文件(开头)。抛出异常的显然不合适。

从剩余的编码中,您可以使用启发式方法来确定编码。

如果仍然是错误的选择,请让用户选择手动更改编码。许多编辑器就是这样完成的,比如 Notepad++。

【讨论】:

  • 谢谢。不幸的是,我无法手动更改编码,因为它是服务器代码。所以基本上我要做的就是对所有可能的 Unicode 编码使用 WideCharToMultiByte(),看看哪个成功?
  • @Qwertypal:见 dxiv 的评论;试试IsTextUnicode
  • @MSalters:虽然这个函数可以给我一个提示,但是它没有给我压力编码
  • @Qwertypal:这是您无法可靠获得的东西。仅 ISO-8859-* 变体几乎无法区分。
【解决方案2】:

您应该使用 W3C 方法,类似于:

  • 如果你知道编码,就用那个

  • 如果有BOM,用它来确定编码

  • 解码为 UTF-8。 UTF-8 有严格的字节序列规则(这是 UTF-8 的目的:能够找到字符的第一个字节)。因此,如果文件不是 UTF-8,很可能它会解码失败:在 ANSI (cp-1252) 上,重音字母后跟符号并不常见,而且每次你​​有这样的符号时都不太可能顺序。 Latin-1:您可能会得到控制字符(而不是符号),但也很少有控制字符 C1 仅在重音字母之后,并且总是 C1 在重音字符之后。

  • 如果解码失败(也许您可以只测试前 4096 个字节,或 127 以上的 10 个字节),请使用操作系统的标准 8 位编码(在 Windows 上可能是 cp-1252)。

这个方法应该很好用。它偏向于 UTF-8,但世界早就朝着这样的方向发展。确定哪个代码页要困难得多。

您可以在最后一步之前添加一个步骤。如果有各种00 字节,您可能是UTF-16 或UTF-32 格式。 Unicode 要求您知道哪种形式(例如来自侧通道),否则文件应该有 BOM。但是你可以根据00在文件中的位置猜出格式(UTF-16LE、UTF-16BE、UTF-32LE、UTF32-BE)(换行,还有一些ASCII字符被认为是常用脚本 em>,所以他们在很多脚本中使用,所以你应该有很多00)。

【讨论】:

    猜你喜欢
    • 2013-11-08
    • 2017-10-15
    • 1970-01-01
    • 2016-08-14
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多