我正在读一个(.txt)文件,第一行的内容只是四个字母:“abcd”。 当我显示这些字母的ASCII码时,我希望我能分别为a,b,c和b找到97,98,99和100。但我找到了两个特殊字符,它们的ASCII码为255和254,用于ÿ和þ。 因此,由于“ÿþabcd”,读取线的长度为6而不是4。这些特殊字符是否必须在任何顺序文本文件的开头插入,或者有什么办法可以避免这两个文件?
答案 0 :(得分:1)
ASCII仅用于小众或古老的系统。您的数据证明您的文件不是ASCII。您必须找出存储文件的字符集和编码。
所有文本都是字符集元素的编码。字符集的元素称为代码点。字符集由一系列代码点及其描述组成。该描述说明了如何在文本中语义使用代码点,例如LATIN CAPITAL LETTER A(A)或N-ARY PRODUCT(∏)。 (呈现码点的样式是字体/字体的范围。)
代码点用非负整数编号。该数字被编码为字节。大多数字符集只有一个编码,这是一个最小大小的无符号整数,可以代表所有代码点。例如,Windows-1252有251个代码点,数字在0到255之间。一个字节足够大,可以代表它们中的任何一个。 Unicode字符集有大约100万个代码点,编号从0到1,114,112。 32位整数足以代表所有这些。这是UTF-32编码。
计算机内存通常是字节可寻址的,文件是字节序列,因此对于一个大整数,问题就变成了,字节存储的顺序是:最重要的字节优先(大端)或最低有效字节优先(小端) 。软件适应或采用某种方式。因此,UTF-32实际上识别出两种编码中的一种:UTF32BE或UTF-32LE。 UTF-32是软件假定的字节顺序的简写。通常,操作系统假定其运行的硬件的字节顺序,程序也遵循。
UTF-32占用了大量空间。最常用的代码点编号低于65,536。因此,如果代码点表示可变数量的较小整数,则可以节省。整数的大小称为代码单元。代码单元的值包含代码单元的一些位,并指示是否有更多的代码单元要跟随具有更多位的代码单元。因此,Unicode有UTF-16LE和UTF-16BE以及UTF-8(和更多)编码。 UTF-16使用一个或两个16位代码单元作为代码点,UTF-8使用一到四个8位代码单元作为代码点。
文件是程序之外的数据。因此,对于读取文本的程序,它必须知道字符集和编码。通常,此元数据不与文件一起存储(在其中或旁边)。这就是你错误地认为你的文件是ASCII的错误。如果您不知道文件的编码,则表示您丢失了数据。你或许可以通过猜测来恢复它。值得注意的是,CP437字符集具有256个代码点,编号为0到255并以一个字节编码。所以每个文件都可以读作CP437;问题是,是吗?即使它看起来是正确的,但它可能不正确,除非它来自1990年左右的西方文化。
关于要猜测的字符集和编码的强有力线索称为字节顺序标记(BOM)。具有大于一个字节的代码单元的重新调用编码具有字节序。字节序是一个硬件问题。因此,尽管可以在系统之间传递文件,并且同意使用哪种字符集和编码方案,但编码的字节顺序属性对每个系统都至关重要。作为第一个字节,在文件中指示字节顺序已成为标准。 Unicode指定用于此目的的代码点,只要它位于文件的开头即可。 (这意味着从文件读取Unicode的程序必须将此元数据与数据分开。)无论代码单元大小如何,许多文件写入库都会写入BOM代码点。所以,你会在UTF-8文件的开头看到它。由于Unicode BOM在每种Unicode编码中看起来都不同,因此它完全标识正在使用的Unicode编码。
您的文件以UTF-16LE BOM开头。将其读作UTF-16LE(如果您的库尚未存在,则丢弃BOM代码点。)
鉴于Unicode BOM的具体性,它的存在是一个强有力的指示,即文件以Unicode编码,实际字节表示哪种Unicode编码。但是,如上所述,这种猜测可能是错误的。
正如@LưuVĩnhPhúc所指出的,目前还不清楚你是如何从你所说的6字节文件中读取“ÿþabcd”的。在十六进制编辑器中打开文件。 UTF-16LE应为FF FE 61 00 62 00 63 00 64 00。