当前位置: 首页 > news >正文

第23讲:文件操作

📚 第23讲:文件操作 📁💾

从“内存瞬时记忆”到“硬盘永久存储”,掌握C语言的“数据存档术”!
让程序学会“记住昨天的故事”!


📂 目录

  1. 为什么使用文件? —— 程序的“永久记忆” 🧠
  2. 什么是文件? —— 程序与数据的“仓库” 🏭
  3. 二进制文件 vs 文本文件 —— 两种存储“密码” 🔐
  4. 文件的打开和关闭 —— 建立“连接”的仪式 🔗
  5. 文件的顺序读写 —— 逐字逐句的“读书写字” 📖✍️
  6. 文件的随机读写 —— “任意跳转”的快进键 ⏭️
  7. 文件读取结束的判定 —— 别再误用 feof
  8. 文件缓冲区 —— 内存与磁盘的“中转站” 🚚

📖 正文开始

你有没有遇到过这样的问题:

  • 程序运行完,数据就没了?
  • 想保存用户上次的设置,却无能为力?

这时候,文件操作就派上用场了!
它让程序的数据不再“朝生暮死”,而是可以持久化存储,随用随取!


为什么使用文件? —— 程序的“永久记忆” 🧠

🌟 生活比喻:笔记本 vs 记忆力

  • 内存:像你的“短期记忆”——程序一关,数据就忘。
  • 文件:像“笔记本”——写下来,永远记得。

文件的核心价值:数据持久化!
即使程序关闭、电脑重启,数据依然存在!


什么是文件? —— 程序与数据的“仓库” 🏭

📦 两大类文件

类型说明示例
程序文件构成程序的代码文件.c, .obj, .exe
数据文件程序读写的数据用户配置、日志、数据库

✅ 本章重点:数据文件——让程序学会“读写外部数据”!


📂 文件名:文件的“身份证”

一个文件必须有唯一标识,格式为:
路径 + 文件名主干 + 后缀
例如:C:\code\test.txt

✅ 简称“文件名”,是程序访问文件的“钥匙”!


二进制文件 vs 文本文件 —— 两种存储“密码” 🔐

🔍 核心区别:存储方式不同

类型存储方式特点示例
文本文件以ASCII码存储人类可读,占用空间大"10000" → 5字节
二进制文件原始二进制形式机器高效,人类难读10000 → 4字节

✅ 实验:10000的存储差异

int a = 10000;
FILE* pf = fopen("test.txt", "wb");
fwrite(&a, 4, 1, pf); // 二进制写入
fclose(pf);

🔍 在VS中打开 test.txt
你会看到一堆“乱码”——这正是 10000 的二进制表示!
它只占 4字节,而文本形式要占 5字节


文件的打开和关闭 —— 建立“连接”的仪式 🔗

🔌 核心函数:fopenfclose

FILE* fopen(const char* filename, const char* mode);
int fclose(FILE* stream);

黄金法则:打开必关闭,否则“内存泄漏”!


🌊 什么是“流”(Stream)?

想象一条“数据之河”:

  • 程序是源头
  • 文件/屏幕/键盘是河流的终点
  • 就是这条河,数据在其中流淌

🧭 标准流:默认打开的“三条河”

说明默认设备常用函数
stdin标准输入流键盘scanf, getchar
stdout标准输出流屏幕printf, putchar
stderr标准错误流屏幕perror

✅ 为什么 printf 不用打开?因为 stdout 已默认打开!


📌 文件指针:文件的“遥控器”

FILE* pf; // 文件指针
  • 每个打开的文件,系统都会创建一个 FILE 结构体,存储文件信息(名字、位置等)。
  • pf 指向这个结构体,通过它就能“遥控”文件。

✅ 你可以不知道 FILE 内部细节,但必须会用 FILE*


🔐 文件打开模式(mode)速查表

模式含义不存在时
"r"读文本报错
"w"写文本创建
"a"追加文本创建
"rb"读二进制报错
"wb"写二进制创建
"ab"追加二进制创建
"r+"读写文本报错
"w+"读写文本创建
"a+"读写追加创建

💡 记忆口诀:

  • r 开头:文件必须存在
  • w 开头:文件不存在就创建,存在就清空!
  • a 开头:追加,永不覆盖!

✅ 示例:写入文件

FILE* pFile = fopen("myfile.txt", "w");
if (pFile != NULL) {fputs("Hello, File!", pFile);fclose(pFile); // ✅ 必须关闭!
}

文件的顺序读写 —— 逐字逐句的“读书写字” 📖✍️

📚 顺序读写函数一览

函数功能适用流
fgetc / fputc字符读写所有流
fgets / fputs字符串读写所有流
fscanf / fprintf格式化读写所有流
fread / fwrite二进制读写文件流

🔁 对比三剑客

函数说明
scanf / printf默认操作 stdin / stdout
fscanf / fprintf可指定文件流
sscanf / sprintf在字符串中读写(内存操作)
✅ 示例:格式化写入
fprintf(pFile, "Name: %s, Age: %d\n", "Alice", 25);

文件的随机读写 —— “任意跳转”的快进键 ⏭️

🎯 fseek:定位“文件光标”

int fseek(FILE* stream, long offset, int origin);
  • origin 起点:SEEK_SET(文件头)、SEEK_CUR(当前位置)、SEEK_END(文件尾)
  • offset 偏移量:正数向后,负数向前
✅ 示例:修改文件内容
fputs("This is an apple.", pFile);
fseek(pFile, 9, SEEK_SET); // 光标跳到第9个字符
fputs(" sam", pFile);      // 写入 → "This is a sample."

📏 ftell:获取当前“位置”

long ftell(FILE* stream);
✅ 示例:获取文件大小
fseek(pFile, 0, SEEK_END); // 跳到末尾
long size = ftell(pFile);  // 获取位置 → 文件大小

🔄 rewind:一键回到“起点”

void rewind(FILE* stream);
✅ 示例:读取刚写入的内容
for (char c = 'A'; c <= 'Z'; c++) {fputc(c, pFile);
}
rewind(pFile); // 回到开头
fread(buffer, 1, 26, pFile); // 读取全部

文件读取结束的判定 —— 别再误用 feof! ❌

⚠️ 重要警告:feof 不是“结束判断器”!

feof 的真正作用:

在读取失败后,判断是否因为“遇到文件尾”导致的失败。


✅ 正确的结束判断方法

文件类型正确做法
文本文件检查 fgetc 是否为 EOF,或 fgets 是否为 NULL
二进制文件检查 fread 返回值是否小于期望读取的数量

✅ 示例1:文本文件读取

int c;
while ((c = fgetc(fp)) != EOF) { // ✅ 正确:用返回值判断putchar(c);
}// 读取结束后,再用 feof 判断原因
if (feof(fp)) {puts("成功到达文件末尾");
} else if (ferror(fp)) {puts("读取时发生错误");
}

✅ 示例2:二进制文件读取

size_t ret = fread(b, sizeof(double), SIZE, fp);
if (ret == SIZE) {puts("读取成功!");
} else {if (feof(fp)) puts("意外到达文件末尾");if (ferror(fp)) perror("读取错误");
}

记住口诀
“先读再判,feof断因,不作判据!”


文件缓冲区 —— 内存与磁盘的“中转站” 🚚

🌟 生活比喻:快递中转仓

  • 你下单(写数据)→ 快递员不马上送(不马上写磁盘)→ 先存中转仓(内存缓冲区)
  • 仓库存满 → 统一发货(刷新到磁盘)

🔍 缓冲区的工作原理

  • 输出:数据先到内存缓冲区,满后才写入磁盘。
  • 输入:磁盘数据先读入缓冲区,程序再从缓冲区取。

⚠️ 危险实验:不刷新的后果

FILE* pf = fopen("test.txt", "w");
fputs("Hello", pf);
Sleep(10000); // 睡10秒 → 打开test.txt,发现是空的!
fflush(pf);     // 刷新缓冲区 → 文件立刻有内容
fclose(pf);     // fclose 也会自动刷新!

关键结论

  • 使用 fflush(pf) 可手动刷新缓冲区。
  • fclose(pf) 会自动刷新并关闭。
  • 不刷新,数据可能“滞留”内存,未写入磁盘!

🎯 总结:文件操作“三要三不要”

要 ✅不要 ❌
fopen 后检查 NULL不要忘记 fclose
要正确判断文件结束不要直接用 feof 判断结束
要理解缓冲区的存在不要假设 fputs 立刻写入磁盘

🎯 恭喜你!
你已经掌握了C语言的“数据存档术”!
现在,你的程序不仅能“思考”,还能“记忆”了!
下一站:预处理指令,揭开C语言“编译前的秘密”!🔍🚀

http://www.dtcms.com/a/504486.html

相关文章:

  • 网站如何不需要备案免费发广告的软件有哪些
  • 网站制作 需要什么网络技术唯品会网站建设特色
  • 如何提高网站点击率dns网站建设
  • 响应式布局的原理网站meta 优化建议
  • 网站建设设计收费网络销售面试问题有哪些
  • mysql8支持远程访问 -mysql5.7支持远程访问
  • DeepSeek+FastGPT+Xinferenc打造企业级知识库
  • 营销型网站费用软件工程35岁就失业吗
  • 开发个网站开票名称是什么意思项目网上备案
  • 2025年-集合类面试题
  • 商城网站静态模板下载安徽安庆天气预报15天
  • 网站任务界面wordpress实例网址
  • Python网络编程调用CnOCR文字识别教程
  • 常熟制作网站的地方广州网页制作
  • 青岛做网站价格关键词排名优化公司
  • 第十九周-训练embedding
  • 何为网站开发如何用cms做网站
  • 2022ICPC区域赛济南站
  • 英文网站建设一般多少钱婚纱摄影图片
  • 家具东莞网站建设技术支持wordpress开启多站点后台没显示
  • 大模型应用开发面经
  • python -day7
  • 解锁AI的“职业技能树“:Claude Skills深度技术解析——从原理到实战的完全指南
  • OpenAI:ChatGPT将开放「成人模式」
  • C程序的核心基石:深入理解与精通函数
  • 网站建设教程赚找湖南岚鸿认 可网站必备功能
  • 阿里巴巴外贸网站首页手机网站布局教程
  • CMOS图像传感器驱动程序原理
  • 移动电商网站设计wordpress 获取文章别名
  • 惠州建设集团网站淘宝上面建设网站安全么