
个人主页 : 流年如夢
专栏 : 《C语言》
文章目录
- 一.了解文件
- 二.二进制文件和文本文件
- 三.文件的打开(fpoen)和关闭(fclose)
- 四.文件的顺序读写([cplusplus链接](https://legacy.cplusplus.com/)👈)
- 五.文件的随机读写
-
- [5.1fseek --> 定位文件指针](#5.1fseek --> 定位文件指针)
- [5.2ftell --> 获取当前偏移](#5.2ftell --> 获取当前偏移)
- [5.3rewind --> 回到文件开头](#5.3rewind --> 回到文件开头)
- 六.文件读取结束的判定(feof与ferror)
- 七.文件缓冲区
- 八.更新文件(r+、w+、a+)
- 🎯总结
- ⚠️易错点
Ladies and gentlemen,本篇文章讲的是文件操作,下面将带领大家学习 文件打开关闭(fopen、fclose)、顺序读写、随机读写、结束判定、文件缓冲区、更新文件 等;全程高能,不容错过!!!
前言
程序运行时的数据都存放在内存中,程序退出后数据就会丢失。如果想让数据持久化保存,就必须用到文件操作。C语言提供了完整的文件读写接口,支持文本和二进制两种存储格式,能实现数据的写入、读取、修改、追加等功能。本篇文章带你从零掌握文件操作,写出稳定、安全、规范的文件处理代码。
一.了解文件
1.1为什么需要使用文件
因为程序退出后,内存数据会被回收 ,数据无法保存;但使用文件可以把数据存放在硬盘 中,实现数据持久化;在下次运行程序时,可以从文件中读取历史数据。
1.2什么是文件
磁盘上的文件就是文件,例如我们电脑都有的C盘和D盘
当然,在程序设计中分为两类:程序文件和数据文件
程序文件:
- 源文件(
.c)- 目标文件(
.obj)- 可执行程序(
.exe)
数据文件(本篇重点):
程序运行时用于读写数据的文件
文件名:
文件名 = 文件路径 + 文件名主干 + 后缀
c
例如:c:\code\test.txt
二.二进制文件和文本文件
2.1文本文件
以ASCII字符形式存储,可以直接看懂的
2.2二进制文件
以内存二进制形式存储,节省空间、读写快
举个例子:
c
#include <stdio.h>
int main()
{
int a = 10000;
FILE* pf = fopen("test.txt", "wb");
fwrite(&a, 4, 1, pf);
fclose(pf);
pf = NULL;
return 0;
}
分析 :wb是以二进制只写方式打开;fwrite是按二进制写入,int只占4字节
运行结果:

在这里程序没有报错,说明运行成功 ;这时双击左上角打开文件test.txt(或ctrl+c),我们可以看到10000以二进制方式 写入文件,如下所示:

三.文件的打开(fpoen)和关闭(fclose)
3.1流和标准流
流(stream):数据传输的抽象,可理解为 "数据的河流"
三个默认标准流:
stdin--> 标准输入(用键盘)stdout--> 标准输出(在屏幕上)stderr--> 标准错误
3.2文件指针
每个打开的文件,系统都会创建一个FILE结构体信息区,我们用FILE*指针来操作文件
3.3fopen --> 打开文件
函数原型:
c
FILE* fopen(const char* filename, const char* mode);
其中打开失败返回NULL ,必须判断;mode是打开方式(例如r、w、a、rb、wb、ab、r+、w+、a+...)
3.4fclose -- > 关闭文件
函数原型:
c
int fclose(FILE* stream);
使用fclose关闭文件,并刷新缓冲区 ;关闭后必须把指针置 NULL
3.5举例
c
#include <stdio.h>
int main()
{
FILE* fp = fopen("test.txt", "r");//这里先打开文件
if (fp == NULL)
{
perror("fopen");
return 1;
}
// 读写操作...
fclose(fp);//最后关闭文件
fp = NULL;
return 0;
}
🧐分析 :先打开判断、用完关闭、最后指针置空;perror是用来直接打印错误原因,方便调试
四.文件的顺序读写(cplusplus链接👈)
表格
| 函数 | 功能 | 适用 |
|---|---|---|
| fputc | 写一个字符 | 所有输出流 |
| fgetc | 读一个字符 | 所有输入流 |
| fputs | 写一行字符串 | 所有输出流 |
| fgets | 读一行字符串 | 所有输入流 |
| fprintf | 格式化写入 | 所有输出流 |
| fscanf | 格式化读取 | 所有输入流 |
| fwrite | 二进制块写入 | 文件流 |
| fread | 二进制块读取 | 文件流 |
4.1fputc与fgetc
4.1.1函数原型

功能:向指定流中写入一个字符 ,写完后文件指针自动后移
参数:
character是要写入的字符;stream是目标文件流返回值:成功返回写入的字符,失败返回
EOF

功能:从指定流中读取一个字符,读完后文件指针自动后移
参数:
stream是要读取的文件流返回值:成功返回读到的字符,读到末尾或出错返回
EOF
4.1.2举例
c
//写入
fputc('a', fp);
//读取
int ch = fgetc(fp);
4.2fputs与fgets
4.2.1函数原型

功能:向文件中写入一个字符串 ,不写入末尾
\0参数:
str是要写入的字符串;stream是目标文件流返回值:成功返回非负数,失败返回
EOF

功能:从文件中读取一行或指定长度字符串
参数:
str是存放读取内容;num是最多读num-1个字符;stream是文件流返回值:成功返回
str,失败或到末尾返回NULL
4.2.2举例
c
fputs("hello world", fp);
char buf[100] = {0};
fgets(buf, 100, fp);
4.3fprintf与fscanf
4.3.1函数原型

功能:格式化写入 文件,用法和
printf几乎一样参数:
stream是目标流;format是格式化字符串;后续为输出参数返回值:成功返回写入字符数,失败返回负数

功能:格式化读取 文件内容,用法和
scanf类似参数:
stream是输入流;format是格式串;后续为地址参数返回值:成功返回读取参数个数,失败或到末尾返回
EOF
4.3.2举例
c
struct Stu
{
char name[20];
int age;
};
//写入
fprintf(fp, "%s %d", s.name, s.age);
//读取
fscanf(fp, "%s %d", s.name, &s.age);//数组name本身就是指针,不需要 &
4.4fwrite与fread
4.41函数原型

功能:以二进制形式 整块写入文件
参数:
ptr是数据地址;size是一个元素大小;count是元素个数;stream是文件流返回值:成功写入的元素个数

功能:以二进制形式 从文件整块读取数据
参数:
ptr是接收数据的缓冲区;size是一个元素大小;count是要读个数;stream是文件流返回值:实际读到的元素个数
4.4.2举例
c
//写入
fwrite(&s, sizeof(struct Stu), 1, fp);
//读取
fread(&s, sizeof(struct Stu), 1, fp);
4.5三组函数对比
| 函数 | 功能 |
|---|---|
| scanf | 从标准输入读 |
| fscanf | 从任意流读 |
| sscanf | 从字符串读 |
| printf | 打印到标准输出 |
| fprintf | 打印到任意流 |
| sprintf | 打印到字符串 |
五.文件的随机读写
5.1fseek --> 定位文件指针
函数原型:


SEEK_SET --> 文件开头
SEEK_CUR --> 当前位置
SEEK_END --> 文件末尾
例如:
c
fseek(fp, offset, origin);
5.2ftell --> 获取当前偏移
函数原型:

功能:返回当前文件指针相对于开头的偏移量
例如:
c
long pos = ftell(fp);
5.3rewind --> 回到文件开头
函数原型:

功能:把文件指针重置到文件开头
例如:
c
rewind(fp);
六.文件读取结束的判定(feof与ferror)
6.1feof
判断是否是正常读到文件末尾
c
if (feof(fp))
printf("读到文件末尾\n");
6.2ferror
判断是否是发生读取错误
c
if (ferror(fp))
printf("读取出错\n");
注意:feof不是用来判断是否结束,而是结束后判断是 "读到尾" 还是 "出错"
七.文件缓冲区
系统会为每个文件自动开辟缓冲区 ;数据先写缓冲区,满了或刷新才写入磁盘;fflush(fp)会强制刷新缓冲区
c
fputs("abc", fp);
fflush(fp);//立即写入磁盘
八.更新文件(r+、w+、a+)
| 模式 | 文件不存在 | 原有内容 | 指针位置 |
|---|---|---|---|
r+ |
打开失败 | 保留 | 开头 |
w+ |
创建新文件 | 清空 | 开头 |
a+ |
创建新文件 | 保留 | 末尾 |
规则:
写完读:必须
fflush或fseek读完写:必须
fseek或rewind
🎯总结
- 文件用于数据持久化,分为文本文件和二进制文件
- 操作流程为
fopen--> 读写 -->fclose--> 置空(NULL) - 打开文件必须判断是否为
NULL - 顺序读写 有
fgetc、fputc、fgets、fputs、fprintf、fscanf - 二进制读写有
fread与fwrite - 随机读写 :
fseek、ftell、rewind - 结束判定 时要用
feof和ferror区分结束原因 - 缓冲区 :
fflush强制刷新,fclose自动刷新 - 更新模式读写切换必须刷新或重定位
⚠️易错点
- 不判断
fopen返回值,直接使用空指针- 忘记
fclose,导致数据丢失、文件占用fclose后不置空,形成野指针- 混淆文本方式与二进制方式
fgets读取时包含\n,处理不当出错- 读写切换不刷新、不定位,导致读写异常
- 用
feof提前判断循环结束,逻辑错误
👀 关注 我们一路同行,从入门到大师,慢慢沉淀、稳步成长
❤️ 点赞 鼓励原创,让优质内容被更多人看见
⭐ 收藏 收好核心知识点与实战技巧,需要时随时查阅
💬 评论 分享你的疑问或踩坑经历,一起交流避坑、共同进步