C 语言文件操作:fopen、fread、fwrite
在 C 语言中,处理文件的核心是三个函数:fopen 打开文件,fread 读取数据,fwrite 写入数据。掌握它们的用法,你就能对磁盘上的任意文件进行读写操作。
第一步:用 fopen 打开或创建文件
调用 fopen 函数来打开一个已有文件,或创建一个新文件。
FILE *fp = fopen("data.bin", "wb");
- 第一个参数是文件路径,如
"data.bin"表示当前目录下的data.bin文件。 - 第二个参数是打开模式,决定文件用途和访问方式。
常用模式如下:
| 模式 | 含义 | 是否清空原内容 | 是否创建新文件 |
|---|---|---|---|
"r" |
只读文本 | 否 | 否 |
"w" |
只写文本 | 是 | 是 |
"a" |
追加文本 | 否 | 是 |
"rb" |
只读二进制 | 否 | 否 |
"wb" |
只写二进制 | 是 | 是 |
"ab" |
追加二进制 | 否 | 是 |
检查返回值是否为 NULL,以确认文件是否成功打开:
if (fp == NULL) {
// 文件打开失败,比如路径不存在或权限不足
perror("无法打开文件");
return -1;
}
第二步:用 fwrite 写入数据到文件
准备要写入的数据,通常是一个变量或数组。
int numbers[3] = {10, 20, 30};
调用 fwrite 将数据写入已打开的文件指针:
size_t written = fwrite(numbers, sizeof(int), 3, fp);
- 第一个参数:指向要写入数据的起始地址(如
numbers)。 - 第二个参数:每个元素的字节大小(如
sizeof(int))。 - 第三个参数:要写入的元素个数(如
3)。 - 第四个参数:之前通过
fopen获得的文件指针(如fp)。
验证写入是否完整:
if (written != 3) {
// 实际写入数量少于预期,可能磁盘已满
perror("写入不完整");
}
注意:
fwrite按原始字节写入,不进行格式转换。写入的是二进制数据,不是文本。
第三步:用 fread 从文件读取数据
准备一块内存用于存放读取的数据:
int buffer[3];
调用 fread 从文件中读取数据:
size_t read = fread(buffer, sizeof(int), 3, fp);
- 参数含义与
fwrite完全对应:- 目标内存地址(
buffer) - 每个元素大小(
sizeof(int)) - 要读取的元素数量(
3) - 文件指针(
fp)
- 目标内存地址(
检查实际读取的数量:
if (read != 3) {
// 可能文件末尾提前到达,或读取出错
if (feof(fp)) {
// 到达文件末尾
}
if (ferror(fp)) {
// 发生读取错误
perror("读取失败");
}
}
fread同样按字节读取,必须确保目标内存足够大,且数据类型与写入时一致。
第四步:关闭文件并释放资源
调用 fclose 关闭文件指针:
fclose(fp);
- 必须执行此操作,否则写入的数据可能滞留在缓冲区而未真正保存到磁盘。
- 关闭后,
fp不应再被使用。
完整示例:写入并读回整数数组
#include <stdio.h>
#include <stdlib.h>
int main() {
// 步骤1:打开文件用于写入
FILE *fp = fopen("numbers.dat", "wb");
if (fp == NULL) {
perror("无法创建文件");
return 1;
}
// 步骤2:写入数据
int data[] = {100, 200, 300};
fwrite(data, sizeof(int), 3, fp);
fclose(fp); // 先关闭写入
// 步骤3:重新打开用于读取
fp = fopen("numbers.dat", "rb");
if (fp == NULL) {
perror("无法读取文件");
return 1;
}
// 步骤4:读取数据
int result[3];
size_t n = fread(result, sizeof(int), 3, fp);
if (n == 3) {
// 成功读取全部数据
printf("读取结果: %d, %d, %d\n", result[0], result[1], result[2]);
}
// 步骤5:关闭文件
fclose(fp);
return 0;
}
运行此程序,将输出:
读取结果: 100, 200, 300
关键注意事项
- 始终检查返回值:
fopen、fread、fwrite都可能失败,必须验证。 - 使用二进制模式处理非文本数据:整数、结构体等必须用
"rb"/"wb",避免换行符转换等问题。 - 不要混用文本与二进制模式:用
"w"写入的文件不能用"rb"可靠读取。 - 文件指针位置自动移动:每次读写后,文件内部的位置指针会前进,连续操作无需手动调整。
- 结构体可直接读写:定义
struct后,可用fwrite(&my_struct, sizeof(my_struct), 1, fp)整体保存。
struct Point {
int x;
int y;
};
struct Point p = {5, 10};
fwrite(&p, sizeof(struct Point), 1, fp);
读取时也按相同方式还原。但注意:此方法生成的文件不具备跨平台兼容性(如不同系统字节序、对齐方式差异)。

暂无评论,快来抢沙发吧!