fread函数是C语言标准库中用于从指定文件流读取二进制数据的函数,定义在stdio.h头文件中,常用于读取二进制文件、结构体数据等场景,和fwrite函数搭配使用可以实现二进制文件的完整读写操作。

fread函数的基本语法
fread函数的原型如下:
#include <stdio.h> size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
各个参数的含义如下:
- ptr:指向接收读取数据的缓冲区的指针,读取到的数据会存放到这个地址对应的内存空间中
- size:每个要读取的元素的大小,单位是字节,通常可以用sizeof运算符获取对应类型的大小
- nmemb:要读取的元素个数
- stream:指向要读取的文件流指针,也就是fopen函数打开文件后返回的文件指针
函数的返回值是实际成功读取的元素个数,如果返回值小于nmemb,可能是到达了文件末尾或者发生了读取错误,可以通过feof或者ferror函数判断具体原因。
fread函数的使用示例
示例1:读取二进制文件中的整数数据
下面的代码演示了如何使用fread函数读取一个包含多个整数的二进制文件:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp = fopen("test.bin", "rb"); // 以二进制读模式打开文件
if (fp == NULL) {
printf("文件打开失败n");
return 1;
}
int arr[5]; // 定义缓冲区存放读取的数据
// 读取5个int类型的数据,每个int大小是sizeof(int)
size_t read_count = fread(arr, sizeof(int), 5, fp);
printf("实际读取到%d个整数n", read_count);
for (int i = 0; i < read_count; i++) {
printf("第%d个整数:%dn", i+1, arr[i]);
}
fclose(fp); // 关闭文件
return 0;
}
示例2:读取结构体数据
fread也常用于读取自定义结构体数据,示例如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义结构体
typedef struct {
int id;
char name[20];
float score;
} Student;
int main() {
FILE *fp = fopen("student.bin", "rb");
if (fp == NULL) {
printf("文件打开失败n");
return 1;
}
Student stu;
// 读取1个Student类型的数据
size_t read_count = fread(&stu, sizeof(Student), 1, fp);
if (read_count == 1) {
printf("学号:%dn", stu.id);
printf("姓名:%sn", stu.name);
printf("分数:%.2fn", stu.score);
} else {
printf("读取失败n");
}
fclose(fp);
return 0;
}
fread函数的使用注意事项
- 打开文件时需要指定正确的模式,读取二进制文件要使用
rb模式,否则在部分系统上可能会出现读取错误 - 缓冲区ptr指向的内存空间必须足够大,能够容纳size*nmemb字节的数据,否则会导致内存越界
- 不要混淆size和nmemb的含义,size是单个元素的大小,nmemb是要读取的元素个数,两者相乘才是总共需要读取的字节数
- 读取完成后要及时关闭文件,避免资源泄露
- 如果读取的是文本文件,虽然也可以用fread,但更推荐使用fgets、fscanf等文本读取函数,fread更适合二进制场景
常见问题解答
为什么fread读取的返回值小于nmemb?
这种情况通常有两种原因,一是已经到达文件末尾,此时feof(stream)会返回非0值;二是发生了读取错误,此时ferror(stream)会返回非0值,可以通过这两个函数判断具体原因。
fread和fgets有什么区别?
fread是二进制读取函数,不会处理换行符等特殊字符,按照指定的字节数读取数据;fgets是文本读取函数,会读取到换行符或者文件末尾为止,并且会在读取的字符串末尾添加空字符,更适合读取文本行。