在下面的代码中,我将创建两个文件,一个是文本格式,另一个是二进制格式。文件的图标显示相同。但是这两个文件的特性完全相同,包括大小,字符集(==二进制)和流(八位字节)。为什么没有文本文件?因为如果我明确创建文本文件,则字符集为ASCII。
编译器版本-gcc(Ubuntu 8.3.0-6ubuntu1)8.3.0。
操作系统-已在Ubuntu 18.10和19.04上试用。
编译器不显示消息。
用于检查文件
file --mime
的命令。命令
Text1.txt
的输出:Text1.txt: application/octet-stream; charset=binary
命令
Text1.txt
的输出:Binary: application/octet-stream; charset=binary
命令
od -xa FILENAME
的输出对于两个文件都是相同的,并且是:
0000000 0021
! 0000001
#include<stdio.h>
void main(){
FILE *fp;
FILE *fp2;
int a = 10111110;
fp2 = fopen("Text1.txt","w");
fputc('!',fp2);
fp = fopen("Binary","wb");
fputc('!',fp);
}
预期的输出是一个字符集为ASCII的文件和一个二进制文件,实际输出均为两个字符集为Binary的文件
答案 0 :(得分:3)
file
命令将文件诊断为二进制而不是ASCII,因为由于错误使用fputc
,正在向文件写入非ASCII字符。
fputc("!",fp2);
不正确。 fputc
的第一个参数应该是带有字符值的int
。 "!"
是一个字符串文字,它是一个数组,会自动转换为指向其第一个字符的指针。
GCC warns you about this,说:“警告:传递'fputc'的参数1会使指针变为整数,而不进行强制转换[-Wint-conversion]”。您显然忽略了该警告。不要那样做。当编译器警告您某些事情时,请注意,诊断问题并修复。
结果是将指针转换为int
,并将此int
传递给fputc
。这可能会导致某些非ASCII字符被写入文件,这进而导致file
命令将文件诊断为二进制文件。
要解决此问题,请将字符串"!"
更改为单个字符'!'
,以便使用fputc
将单个字符传递给fputc('!',fp2);
。
此外,main
不应用void main()
声明。用int main(void)
或int main(int argc, char *argv[])
或其他实现定义的方式声明它。
在Unix系统上,带有更正代码的结果文件将是相同的。 Core Unix不区分文本文件和二进制文件,只是某些应用程序可以使用元数据(例如“扩展属性”)以各种方式表征文件。错误代码产生的文件可能相同也可能不同,因为不同位置的相同字符串文字可能具有或不具有相同的地址,因此所得的指针可能具有或不具有相同的值。
答案 1 :(得分:0)
C在二进制流和文本流中提供了原理上的区别。遍历文本流的数据可能需要进行与实现相关的转换:
在输入和输入时可能必须添加,更改或删除字符 输出以符合表示文本的不同约定 主机环境。因此,不必一对一 流中字符与 外部代表。从文本流读取的数据将 必须比较等于先前写入的数据 仅在以下情况下流:数据仅由打印字符组成,并且 控制字符水平制表符和换行符;没有换行 字符前面紧跟空格字符;最后一个 character是换行符。是否空格字符 在读取时出现换行符之前立即写出 in是实现定义的。
但是,实际上,在任何可能会遇到的系统上,您将看到的针对字节流的唯一转换是在使用文本中的回车符/换行符对的系统(主要是Windows)上的行终止符转换文件。 C文本模式流将在该外部表示形式和C的仅换行符内部表示形式之间进行转换。
但是,在Linux和现代的基于BSD的macOS上,甚至没有—在实际操作中,这些操作系统在文本文件和二进制文件之间没有任何区别,并且两种生成文件的机制也就不足为奇了。文件产生相同的文件。
这是一个完全独立的问题,试图猜测文件类型的外部程序如何解释任何给定的文件,尤其是很短的文件。如果文件包含单词和句子形式的正版文本,则最好将文件检测为文本。