3
  1. 为什么保存为 UTF8(在 Notepad++ 中)的文件在我在 c++ 程序中打开的 fstream 的开头有这个字符?

    ´╗┐

    我不知道它是什么,我只知道当我保存为 ASCII 时它不存在。更新:如果我将它保存为 UTF8(没有 BOM),它就不存在了。

  2. 如何在 c++ 中检查文件的编码(ASCII 或 UTF8,其他所有内容都将被拒绝;))。就是这些字符吗?

谢谢!

4

5 回答 5

7

当您将文件保存为 UTF-16 时,每个值是两个字节。不同的计算机使用不同的字节顺序。有些将最高有效字节放在首位,有些将最低有效字节放在首位。Unicode 保留了一个特殊的代码点 (U+FEFF),称为字节顺序标记 (BOM)。当程序以 UTF-16 写入文件时,它会将这个特殊的代码点放在文件的开头。当另一个程序读取一个 UTF-16 文件时,它知道那里应该有一个 BOM。通过将实际字节与预期 BOM 进行比较,它可以判断读取器是否使用与写入器相同的字节顺序,或者是否必须交换所有字节。

保存 UTF-8 文件时,字节顺序没有歧义。但是有些程序,尤其是为 Windows 编写的程序,仍然会添加一个 BOM,编码为 UTF-8。当您将 BOM 代码点编码为 UTF-8 时,您将获得三个字节,即 0xEF 0xBB 0xBF。这些字节对应于大多数 OEM 代码页中的绘图字符(这是 Windows 上控制台窗口的默认设置)。

支持这样做的理由是它将文件标记为真正的 UTF-8,而不是其他一些本机编码。例如,西方 Windows 上的许多文本文件都在代码页 1252 中。使用 UTF-8 编码的 BOM 标记文件可以更容易区分。

反对这样做的理由是,许多程序都期望 ASCII 或 UTF-8,并且不知道如何处理额外的三个字节。

如果我正在编写一个读取 UTF-8 的程序,我会在开始时检查这三个字节。如果他们在那里,请跳过他们。

更新: 您可以将U+FEFF ZERO WIDTH NO BREAK字符转换U+2060 WORD JOINER为文件开头以外的字符 [Gillam, Richard, Unicode Demystified , Addison-Wesley, 2003, p. 108]。我的个人代码就是这样做的。如果在解码 UTF-8 时,我在文件开头看到 0xEF 0xBB 0xBF,我认为这是我确实拥有 UTF-8 的一个快乐信号。如果文件不是以这些字节开头,我只是正常进行解码。如果稍后在文件中解码时遇到 U+FEFF,我会发出 U+2060 并继续。这意味着 U+FEFF 仅用作 BOM 而不是其已弃用的含义。

于 2010-07-25T15:57:17.323 回答
1

为什么保存为 UTF8 的文件开头没有这个字符 [...] 我不知道它是什么,我只知道保存为 ASCII 时它不存在。

我想您指的是字节顺序标记 (BOM) U+FEFF,一个零宽度、不间断的空格字符。这里(notepad++ 5.4.3)保存为 UTF-8 的文件,EF BB BF开头有字符。我想这就是用 UTF-8 编码的 BOM。

如何检查文件的编码

你不能。你必须知道你的文件是用什么编码编写的。虽然 Unicde 编码的文件可能以 BOM 开头,但我认为他们没有这样做的要求。

于 2010-07-25T15:51:51.657 回答
1

在不知道这些字符到底是什么(即,没有十六进制转储)的情况下,这只是一个猜测,但我的直接猜测是你所看到的是采用字节顺序标记(BOM)和(某种)编码的结果它作为UTF-8。从技术上讲,您不允许/不应该这样做,但实际上它实际上相当普遍。

澄清一下,您应该意识到这并不是真正的字节顺序标记。字节顺序标记的基本思想根本不适用于 UTF-8。从理论上讲,永远不应该将 UTF-8 编码应用于 BOM - 但您可以忽略这一点,并将正常的 UTF-8 编码规则应用于构成 BOM 的值,如果您愿意的话。

于 2010-07-25T15:57:26.143 回答
1

Regarding your second point, every valid ASCII string is also a valid UTF-8 string, so you don't have to check for ASCII explicitly. Simply read the file using UTF-8, if the file doesn't contain a valid UTF-8 string, you will get an error.

于 2010-07-25T19:25:24.667 回答
0

我猜你的意思是问,为什么它有这些字符。这些字符可能是字节顺序标记,根据 UTF-8 中的链接,它是字节 EF BB BF。

至于知道文件的编码是什么,您无法从文件本身得出。您必须提前知道(或询问向您提供文件的用户)。为了更好地理解编码而无需大量阅读,我强烈推荐 Joel Spolsky 的The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

于 2010-07-25T15:55:36.460 回答