C语言中操作文件-用二进制的方式读写文件-学习笔记-64

引言

前面我们说,使用 fprintf 和 fscanf 确实很方便,也很好理解,但是频繁的进行读写,二进制和 ASCII 码转来转去不是事,太耽误时间了,那么今天我们就来学习如何读取和写入二进制数据,还能一次输入输出结构体等成组的数据哦~

二进制文件读写函数

一般形式

fread (buffer,size,count,fp);
fwrite(buffer,size,count,fp);

参数说明

  • buffer:是一个地址,对 fread 而言,buffer 代表着那些从文件读入的数据在内存存储区的地址。
  • size:要读写多少个字节数。
  • count:要读写多少个数据项,一个数据项的长度是 size 字节
  • fp:FILE 文件类型指针

我知道这里的 buffer、size 和 count 把大家绕晕了,我再来说明一下

1
2
3
float f[20];
fread(f,4,10,fp);
//从 fp 指向的文件中取出10个数据项,每项数据4个字节。存储到数组 f 中

这里的 f 表示的是这个数组的首元素地址。在举个例子:

1
2
3
4
5
6
struct Student_type{
char name[10];
int num;
int age;
char addr[30];
}stud[40];

我们定义了一个结构体,包含学生的各种数据
然后又用该结构体声明了一个数组,有40个元素
这40个元素都包含着每一个学生的姓名、学号、年龄、地址等信息
假设,学生的数据已经存放在磁盘文件中,我们用 for 循环读入这40个学生的数据。

1
2
3
for(int i=0;i<40;i++){
fread(&stud[i],sizeof(struct Student_type),1,fp);
}

执行40次这样的循环,每次都从 fp 指向的文件读入结构体数组 stu 的一个元素。同样的方式,我们也可以把数据输出到磁盘文件中:

1
2
3
for(int i=0;i<40;i++){
fwrite(&stu[i],sizeof(struct Student_type),1,fp);
}

返回结果
成功:返回 count 的个数,即输入/输出成功的个数

例子

从键盘输入3个学生的有关数据,把他们转存到磁盘文件上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct Student)
int main(){
struct Student{
int num;
char name[10];
float score;
}stu[3];
printf("请输入三个学生的信息:\n");
for(int i=0;i<3;i++){
scanf("%d %s %f",&stu[i].num,stu[i].name,&stu[i].score);
}
//开始写入
FILE *fp;
fp=fopen("/Users/liulin/1.txt","wb");
for(int i=0;i<3;i++){
fwrite(&stu[i],LEN,1,fp);
}
fclose(fp);
// 关闭后再次读入
struct Student stu_read[3];
fp=fopen("/Users/liulin/1.txt","rb");
for(int i=0;i<3;i++){
fread(&stu_read[i],LEN,1,fp);
printf("%d %s %3.1f\n",stu_read[i].num,stu_read[i].name,stu_read[i].score);
}
fclose(fp);
return 0;
}

输出结果

请输入三个学生的信息:
10001 liulin 76.7
10002 bliner 99.6
10003 lin 88.6

10001 liulin 76.7
10002 bliner 99.6
10003 lin 88.6

1.txt 文件存储

1127 0000 626c 696e 6572 0000 0100 0000
cdcc c742 1227 0000 6c69 756c 696e 0000
0000 0000 9a99 c742 1327 0000 6c69 6e00
0000 0000 0000 0000 6666 c742

解析

  • 结构体的长度是其成员长度之和,我们首先定义了一个常量 LEN,存储这个结构体的长度,方便我们等下 fread 和 fwrite 的时候使用。
  • 因为我们写入的时候,直接将数组中的结构体数据写入到1.txt 文本中了,所以文本中的内容是二进制文件。
  • 我们最后输出的时候,重新将文件读入,并且输出了这个二进制文件,发现和我们输入的内容是一样的。
  • 需要注意的是,我们从终端输入的回车+换行符,是 ASCII 的,送到程序中,转换成二进制,并且回车转换成一个换行符。输出到文件的时候直接存储的是二进制文件,所以不存在转换问题。再次读入时,内存中的数据没变,再次在终端显示的时候,又从一个换行符转换成了回车+换行符的形式。

尾巴

这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。


-------------The End-------------
欢迎请我喝咖啡哦~!