文件读写:fwrite与fprintf的区别(即二进制方式和文本方式的区别)

 C语言把文件看作一个字符(字节)的序列,即由一个一个字符(字节)的数据顺序组成。根据数据的组织形式,可分为ASCII文件和二进制文件。ASCII文件又称为文本(text)文件,它的每个字节放一个ASCII代码,代表一个字符。二进制文件是把内存中的数据按其在内在中的存储形式原样输出到磁盘上存放。

fprintf(fp, "%d", buffer); 是将格式化的数据写入文件
fprintf(文件指针,格式字符串,输出表列);

fwrite(&buffer, sizeof(int), 1, fp);是以二进位方式写入文件
fwrite(数据,数据类型大小(字节数),写入数据的最大数量,文件指针);

由于fprintf写入时,对于整数来说,一位占一个字节,比如1,占1个字节;10,占2个字节;100,占3个字节,10000,占5个字节
所以文件的大小会随数据的大小而改变,对大数据空间占用很大。
而fwrite是按二进制写入,所以写入数据所占空间是根据数据类型来确定,比如int的大小为4个字节(一般32位下),那么整数10所占空间为4个字节,100、10000所占空间也是4个字节。所以二进制写入比格式化写入更省空间。

因此,
对于1 2 3 4 5 6 7 8 9 0 十个整数,用fprintf写入时,占10个字节;而用fwrite写入时,占40个字节。
对于100 101 102 103 104 105 106 107 108 109 110 这十个整数,用fprintf写入时,占30个字节;而用fwrite写入时,占40个字节。
对于10000 10100 10200 10300 10400 10500 10600 10700 10800 10900 11000 这十个整数,用fprintf写入时,占50个字节;而用fwrite写入时,还是占40个字节。

fwrite 函数按照指定的数据类型将矩阵中的元素写入到文件中。写二进制文件
其调用格式为:COUNT=fwrite (fid, A, precision)其中COUNT返回所写的数据元素个数,fid为文件句柄,A用来存放写入文件的数据,precision用于控制所写数据的类型,其形式与fread函数相同。
fprintf 写文本文件 函数的调用格式为:COUNT= fprintf(fid, format, A)其中A存放要写入文件的数据。先按format指定的格式将数据矩阵A格式化,然后写入到fid所指定的文件。format用以控制读取的数据格式,由%加上格式符组成,常见的格式符有d,f,c,s。fid为文件句柄。

看如下的例子:

[cpp]  view plain  copy
 print ?
  1. #include <stdio.h>  
  2. void main()  
  3. {  
  4.     int num;  
  5.     char name[5];  
  6.     FILE *fp;  
  7.     if ((fp = fopen("t.txt""w")) == NULL)  
  8.         printf("cannot open file!\n");  
  9.    scanf("%d %s",&num,name);  
  10.    fprintf(fp, "%d %s", num, name);  
  11.    fclose(fp);  
  12.    if ((fp = fopen("tt.txt""w")) == NULL)  
  13.         printf("cannot open file!\n");  
  14.    fwrite(&num, sizeof(int), 1, fp);  
  15.    fwrite(name, sizeof(char), 5, fp);  
  16.    fclose(fp);   
  17. }  

输入:100000 liuj

使用记事本打开两个文本文件t.txt和tt.txt,结果如下:

t.txt: 100000 liuj    (文件大小:11字节)

tt.txt:爢 liuj (乱码,文件大小:9字节)

当我们按照文本方式往文件中写入数据时,一旦遇到换行字符(ASCII为10),则会转换为回车-换行(ASCII为13、10)。在读取文件时,一旦遇到回车-换行的组合(即连续的ASCII 13、10),则会转换为换行字符(ASCII为10)。

当我们按照二进制方式往文件中写入数据,则将数据在内存中的存储形式原样输出到文件中。

------------------------------------------------------------------------------------

《计算机组成原理》
比如
int v=1;
fwrite(&v,sizeof(int),1,f);//文件中被写四个字节0x01 0x00 0x00 0x00(32位int,小端存储)
fprintf(f,"%d",v);//文件中被写一个字节0x31(即'1'的ASCII码)
又比如
int v=0x12345678;
fwrite(&v,sizeof(int),1,f);//文件中被写四个字节0x78 0x56 0x34 0x12(32位int,小端存储)
fprintf(f,"%x",v);//文件中被写八个字节0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38
fprintf(f,"%d",v);//文件中被写九个字节0x33 0x30 0x35 0x34 0x31 0x39 0x38 0x39 0x36
(因为0x12345678==305419896)

-----------------------------------------------------------------------------------

一句话表述:fwrite是将数据不经转换直接以二进制的形式写入文件,而fprintf是将数据转换为字符后再写入文件。

这样就导致:

当使用fwrite将一个int型数字65写入文本文件时,由于65对应的二进制数是1000001,十六进制数是0x41,存储的是以二进制的形式1000001.在notepad++中使用十六进制方式打开显示的是:0x0041,转换为十进制则为65,使用记事本打开这个文本文件后显示的是A,因为记事本程序默认为存储在文本文件中的数据都是ASCII码形式存储,它把65当做ASCII码翻译为字符A。

当使用fpintf将一个int型数字65写入文本文件时,将65每一位转换为ASCII码存储,6、5分别对应ASCII码54、53,存储的是ASCII码54、53.在notepad++中使用十六进制方式打开显示的是:3635,转换为十进制则为54、53,这正是数字6、5的ASCII码。使用记事本打开这个文本文件时,记事本将存储在其中的54、53当做ASCII码翻译为字符6、5显示,我们看到的是便是字符65。

  • 20
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
### 回答1: 是的,您说得对。二进制文件文本文件区别在于它们处理文件内容的方式不同。二进制文件包含的是二进制数据,而文本文件包含的是字符数据。因此,如果您将二进制文件的扩展名设置为 .txt,那么文本编辑器可能会尝试解释二进制数据为字符数据,导致数据损坏。同样,二进制文件读写函数fread和fwrite也会受到影响,因为它们是基于二进制数据的读写函数。建议在创建二进制文件时使用其他扩展名,例如 .bin 或者 .dat。 ### 回答2: 二进制文件名不能用.txt作为扩展名,否则二进制文件读写函数fread和fwrite将出错的原因是因为使用.txt作为扩展名会默认将文件视为文本文件进行读写操作。而文本文件二进制文件在读写方式上有所不同。 文本文件是指以文本形式保存数据的文件,其中的数据是以字符的形式编码的。文本文件的读写是以字符为单位进行的,常用的读写函数是fscanf和fprintf。使用这些函数进行读取和写入时,会自动进行字符编码的转换,以文本格式读取和写入数据。 与之不同的是,二进制文件是以字节为单位进行读写的文件。它并不对数据进行编码转换,仅将数据以二进制形式直接读取和写入。在二进制文件读写过程中,使用的函数是fread和fwrite。这些函数会按照指定的字节数读取和写入数据,不会对数据进行字符编码或转换。 当我们将二进制文件使用.txt作为扩展名保存时,操作系统会默认其为文本文件。在使用fread和fwrite进行读写时,函数会按照字节为单位进行读写,但由于文件被识别为文本文件,系统会根据字符编码对数据进行解析。由于二进制文件并不是以字符的形式编码,因此读取和写入数据时可能会产生错误。 为了避免这种错误,我们应该将二进制文件的扩展名设计为其他形式,例如.bin、.dat等,以明确表示该文件是以二进制格式存储的。这样,在使用fread和fwrite函数读写二进制文件时,系统会按照字节为单位直接进行读写,不会进行字符编码的解析,从而确保数据的正确读写。 ### 回答3: 二进制文件是以二进制形式存储的文件,其内容是由0和1组成的,不同于文本文件采用ASCII码来表示字符。而文件的扩展名旨在标识文件的格式或类型,以方便操作系统和用户进行区分。 在二进制文件的读写过程中,我们使用的函数是fread和fwrite。这两个函数的主要作用是读取或写入指定长度的数据,其中数据以字节为单位进行操作。而文本文件的读写函数是以字符为单位进行操作的。因此,如果将扩展名设置为.txt,即表示该文件文本文件,而不是二进制文件。 由于二进制文件的特殊性,如果我们使用fread和fwrite函数读写一个以.txt作为扩展名的文件时,函数会将文件内容按照字符的形式进行读写,遇到二进制数据时会引发错误,导致读取或写入的文件内容出现混乱或无法正常操作的情况。 为了避免这种错误,我们应该根据文件的实际内容和用途来选择合适的扩展名,对于二进制文件,常见的扩展名有.bin、.dat等。这样在使用fread和fwrite函数读写数据时,函数会按照字节为单位进行操作,确保文件内容的准确性和完整性。 因此,为了正确读写二进制文件,我们应该将扩展名设置为与其内容类型相对应的合适的格式,切勿将二进制文件以.txt作为扩展名进行命名。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值