如何将文件内容标识为ASCII或二进制 你如何用C++来定义文件内容,或者用C++?< /p>

如何将文件内容标识为ASCII或二进制 你如何用C++来定义文件内容,或者用C++?< /p>,c++,ascii,binaryfiles,file-format,C++,Ascii,Binaryfiles,File Format,,这取决于你对ASCII的定义。您可以使用ASCII代码检查值,每个文件的内容都是二进制的。所以,不知道别的,你不能确定 ASCII是一个解释问题。如果你在文本编辑器中打开一个二进制文件,你就会明白我的意思 大多数二进制文件都包含一个固定的头(每种类型),您可以查找,也可以将文件扩展名作为提示。如果需要UTF编码的文件,可以查找字节顺序标记,但它们也是可选的 除非您更仔细地定义您的问题,否则不可能有一个明确的答案。您使用stream.get()的普通循环对其进行迭代,并检查您读取的字节值是否为如

,这取决于你对ASCII的定义。您可以使用ASCII代码检查值,每个文件的内容都是二进制的。所以,不知道别的,你不能确定

ASCII是一个解释问题。如果你在文本编辑器中打开一个二进制文件,你就会明白我的意思

大多数二进制文件都包含一个固定的头(每种类型),您可以查找,也可以将文件扩展名作为提示。如果需要UTF编码的文件,可以查找字节顺序标记,但它们也是可选的


除非您更仔细地定义您的问题,否则不可能有一个明确的答案。

您使用stream.get()的普通循环对其进行迭代,并检查您读取的字节值是否为
如果文件只包含十进制字节9–13、32–126,则可能是纯ASCII文本文件。否则,就不是了。但是,它可能仍然是另一种编码中的文本

如果在上述字节的
之外,该文件仅包含十进制字节128–255,则它可能是一个基于8位或可变长度ASCII编码的文本文件,如ISO-8859-1、UTF-8或ASCII+Big5。如果不是,对于某些目的,您可以在这里停止并认为文件是二进制的。但是,它可能仍然是16位或32位编码的文本

如果文件不满足上述约束条件,请检查文件的前2–4个字节是否存在:

  • 如果前两个字节为十六进制
    FE FF
    ,则文件暂定为UTF-16 BE
  • 如果前两个字节为十六进制
    FF FE
    ,而后两个字节为十六进制
    00
    ,则文件暂定为UTF-16 LE
  • 如果前四个字节为十六进制
    00 FE FF
    ,则文件暂定为UTF-32 BE
  • 如果前四个字节为十六进制
    FF FE 00
    ,则文件暂定为UTF-32 LE
如果通过上述检查确定了暂定编码,则只检查下面相应的编码,以确保该文件不是碰巧与字节顺序标记匹配的二进制文件

如果尚未确定暂定编码,则该文件可能仍然是这些编码之一中的文本文件,因为字节顺序标记不是必需的,因此请检查以下列表中的所有编码:

  • 如果文件仅包含十进制值为9–13、32–126和128或以上的大端双字节字,则该文件可能是UTF-16 BE
  • 如果该文件仅包含小数点为9–13、32–126和128或以上的小尾端双字节字,则该文件可能是UTF-16 LE
  • 如果该文件仅包含具有十进制值9–13、32–126和128或以上的大端四字节字,则该文件可能是UTF-32 BE
  • 如果该文件仅包含小数点为9–13、32–126和128或以上的小尾端四字节字,则该文件可能是UTF-32 LE

如果在所有这些检查之后,您仍未确定编码,则该文件不是我所知道的任何基于ASCII的编码中的文本文件,因此对于大多数目的,您可能认为它是二进制的(它可能仍然是非ASCII编码中的文本文件,如EBCDIC,但我怀疑这超出了您关注的范围)。.

看看它是如何工作的;它有三种确定文件类型的策略:

  • 文件系统测试
  • 测验
  • 语言测试

根据您的平台和可能感兴趣的文件,您可以查看其实现,甚至调用它。

我的文本编辑器决定是否存在空字节。实际上,这非常有效:没有空字节的二进制文件非常罕见。

要进行检查,必须以二进制文件的形式打开该文件。无法以文本形式打开文件。ASCII实际上是二进制的子集。 之后,必须检查字节值。ASCII的字节值为0-127,但0-31是控制字符。TAB、CR和LF是唯一常见的控制字符。 你不能(便携地)使用“A”和“Z”;不能保证这些是ASCII(!)格式的。 如果你需要它们,你必须定义它们

const unsigned char ASCII_A = 0x41; // NOT 'A'
const unsigned char ASCII_Z = ASCII_A + 25;

如果真正的问题是如何检测ASCII码,那么litb的答案是正确的。但是,如果san是在知道如何确定文件是否包含文本之后才发现的,那么问题就变得更加复杂了。ASCII只是一种越来越不受欢迎的文本表示方式。Unicode系统——UTF16、UTF32和UTF8越来越流行。理论上,可以通过检查前两个字节是否为unicocde字节顺序标记(BOM)0xFEFF(如果字节顺序颠倒,则为0xFFFE)来轻松测试它们。然而,由于这两个字节破坏了Linux系统的许多文件格式,因此无法保证它们存在。此外,二进制文件可能以0xFEFF开头

如果文件是unicode,查找0x00(或其他控制字符)也不会有帮助。如果文件是UFT16,并且该文件包含英文文本,那么每隔一个字符将是0x00

如果您知道文本文件将使用的语言,那么就可以分析字节并从统计上确定它是否包含文本。例如,英语中最常见的字母是E后跟T。因此,如果文件中包含的E和T比Z和X多得多,则可能是文本。当然,有必要将其作为ASCII和各种Unicode进行测试,以确保安全

如果文件不是用英语编写的,或者您希望支持多种语言,那么剩下的两个选项是查看Windows上的文件扩展名,并对照“magic file”代码数据库检查前四个字节,以确定
const unsigned char ASCII_A = 0x41; // NOT 'A'
const unsigned char ASCII_Z = ASCII_A + 25;