今天我们来聊聊 C 语言里的一个"超能力"------文件操作。
你是不是经常遇到这种尴尬:辛辛苦苦在程序里算了一堆数据,结果一关黑窗口,啥都没了?就像你熬夜写了篇小作文,没点保存就关了电脑,第二天想起来直接想扇自己一巴掌。
其实,C语言早就给我们准备了"存档"功能,这就是文件操作。它能让你的数据从"内存的过客"变成"硬盘的常住居民"。今天咱们就把这套"存盘大法"彻底聊透,保证你看完就能上手!
一、找路:绝对路径与相对路径
在读写文件之前,你得先告诉电脑:"我要操作哪个文件?" 这就涉及到路径。
- 绝对路径 :就像你的家庭住址,从省/市/区一直到门牌号,独一无二。
- Windows 上长这样:
C:\bitejiuyeke\code\test.c - Linux/macOS 上长这样:
/home/alice/Documents/report.txt - 特点:不管你在哪个角落,只要报出这个地址,系统就能精准定位。缺点是太长了,写起来手酸。
- Windows 上长这样:
- 相对路径 :就像你跟朋友说"在我家隔壁"。它是相对于你当前所在目录 来说的。
./test.txt:当前目录下的 test.txt(./就是"这里")。../image/labubu.png:上一级目录里的 image 文件夹下的 labubu.png(..就是"回上一级")。- 特点:简洁,但如果你挪了位置,可能就找不到了。
闲聊:写代码时,如果文件就在项目文件夹里,用相对路径最方便;如果要指定系统里的某个固定位置,那就得用绝对路径。
二、文件的"双重人格":文本文件 vs 二进制文件
这是新手最容易迷糊的地方。同样是一堆 0 和 1,怎么还分两种?
1. 文本文件:人类能看懂的"电报"
文本文件里存的都是字符 (字母、数字、符号),比如 .txt、.c、.html。
计算机只认识数字,那怎么存文字?靠字符编码。
想象你要给外国朋友发电报,你们约定:1=A, 2=B...。你发 8-5-12-12-15,对方就知道是 HELLO。这个"约定"就是编码。
- ASCII:最基础的编码,只能表示英文字符(128个)。
- UTF-8:现在最流行的编码,能表示全世界几乎所有文字(比如中文"你"=20320)。
特点:你可以用记事本直接打开,看到的是正常的文字。
2. 二进制文件:机器才懂的"天书"
二进制文件直接存储原始字节 ,没有编码转换。比如 .exe、.jpg、.mp3。
如果你用记事本强行打开一张 .jpg 图片,看到的就是一堆乱码。因为记事本想把它当文本解读,但那其实是照片的像素数据。
通俗比喻:
- 把自拍照保存为文本文件:就像把照片撕碎,然后用文字描述"第1个像素是红色,第2个是蓝色...",毫无意义,打开全是乱码。
- 保存为二进制文件 (
.jpg):直接把原始数据存进去,文件小巧,用图片软件一打开,就是完整的你。
三、FILE 指针:你的"文件管家"
在 C 语言里,每打开一个文件,系统就会在内存里建一个文件信息区 ,里面记录了文件名、状态、位置等。这个信息区是一个结构体,叫 FILE。
我们不用自己定义 FILE,只需要用一个指针来指向它:

这个 fp 就是你的"文件管家",后续所有操作都靠它。
四、开门与关门:fopen 和 fclose
操作文件就像用冰箱:先开门,拿/放东西,关上门。
1. fopen:开门

filename:文件名(可以带路径)。mode:打开方式(只读、只写、追加等)。- 返回值 :成功返回
FILE*指针,失败返回NULL!
常用 mode 速查表:
| 模式 | 含义 | 文件不存在时 |
|---|---|---|
"r" |
只读(文本) | 报错 |
"w" |
只写(文本,清空原有内容) | 新建 |
"a" |
追加(文本,写在末尾) | 新建 |
"rb" |
只读(二进制) | 报错 |
"wb" |
只写(二进制) | 新建 |
避坑 :一定要检查
fopen的返回值!不然门都没打开,你还在那傻傻地读,程序直接崩给你看。
2. fclose:关门

不用了一定要关门!不然数据可能没真正写进去,还会造成资源泄漏。
五、顺序读写:流水账式搬运
这是最常用的操作,就像看书一样,从头到尾一页页来。
1. 字符搬运工:fputc / fgetc
fputc('A', fp):把一个字符A写入文件。fgetc(fp):从文件读一个字符。- 注意:每读写一个字符,文件内部的"光标"会自动往后移一位。
2. 字符串搬运工:fputs / fgets
fputs("hello", fp):写入字符串(注意:遇到\0就停,不写入\0)。fgets(arr, 10, fp):从文件读一行(最多9个字符,最后加\0),遇到换行符也会读进去。
3. 格式化搬运工:fprintf / fscanf
这俩就是 printf 和 scanf 的文件版。

读的时候:

简直和 scanf 一模一样,只是多了个文件指针。
4. 二进制搬运工:fwrite / fread
这是效率最高的方式,直接按数据块读写,不经过任何编码转换。

读的时候:

适用场景 :结构体、数组等需要快速存取的场合。比如游戏存档,直接 fwrite 把角色属性结构体存进去,下次 fread 读出来,爽歪歪!
六、随机读写:想跳哪就跳哪
有时候你不想从头读,想直接看第100页,这时候就需要随机读写。
1. fseek:定位光标

三个基准点:
SEEK_SET:文件开头SEEK_CUR:当前位置SEEK_END:文件末尾
2. ftell:我在哪?

妙用:快速计算文件大小!

3. rewind:倒带

七、别崩,先查错:feof 和 ferror
读文件时,如果返回了 EOF(-1),不一定就是"读完了",也可能是"读取出错了"。
feof(fp):如果返回真,说明是正常读到文件末尾了。ferror(fp):如果返回真,说明是读取过程中发生了错误(比如磁盘坏了)。
所以,严谨的写法是:

八、终极实战:拷贝视频
学了这么多,咱们来个硬核的------用 C 语言拷贝一个视频文件!
原理很简单:用 fread 从源视频读一块数据到缓冲区,再用 fwrite 把这块数据写到新文件里,循环往复,直到读完。

看,这就是文件操作的魅力!不管你是什么格式的文件,在我眼里都是二进制流,统统能拷!
九、总结时间到啦!!!
好了,今天关于文件操作的闲聊就到这里。咱们回顾一下重点:
- 路径:绝对路径是"身份证",相对路径是"在我旁边"。
- 文件类型:文本文件给人看(有编码),二进制文件给机器看(直接存)。
- 开关门 :
fopen必须检查NULL,fclose用完必关。 - 顺序读写 :字符用
fputc/fgetc,字符串用fputs/fgets,格式化用fprintf/fscanf,二进制块用fwrite/fread。 - 随机读写 :
fseek跳来跳去,ftell查位置,rewind回开头。 - 错误处理 :
feof查是否读完,ferror查是否出错。
掌握了文件操作,你的程序就不再是"金鱼记忆"了,它能把数据永久保存下来。