引入
我们讲了这么久的文件,知道了文件名、内存缓冲区、缓冲区中的文件信息区以及定义一个 FILE 结构体变量和指针。今天我们就来尝试打开和关闭一个文件。
fopen 函数打开文件
ANSI C 规定了用标准输入输出函数 fopen 来实现打开文件
一般形式
fopen (文件名 , 使用文件方式);
例如:
1 | fopen("a1","r"); |
a1:是要打开的文件名,也可以是字符数组的首地址
r:使用文件方式(r 表示 read 读入)
fopen 函数的返回值是指向 a1 文件的指针
,也就是 a1 在内存中的文件信息区的起始地址
。所以,我们经常将 fopen 函数的返回值给一个指向文件的指针变量。
1 | FILE *fp; //定一个指向文件的指针变量 fp |
此时,我们就可以说 fp 是指向文件 a1 的文件指针。打开这个文件后,我们发现,打开一个文件需要一下三个信息:
- 需要打开的文件名
- 使用文件的方式(如r, read 读入)
- 让哪个指针变量指向这个被大开的文件
注意
FILE *fp 只是初始化一个 fp 指针变量,指针变量中是没有值的,在 fopen 后在获取到 fopen 的文件的文件信息区起始地址。
常用使用文件方式表
文件使用方式 | 含义 | 如果文件不存在 |
---|---|---|
“r”(只读) | 为了输入数据,打开一个文本文件 | 出错 |
“w”(只写) | 为了输出数据,打开一个文本文件 | 建立新文件 |
“a”(追加) | 向文本文件尾部添加数据 | 出错 |
“rb”(二进制只读) | 为了输入数据,打开一个二进制文件 | 出错 |
“wb”(二进制只写) | 为了输出数据,打开一个二进制文件 | 建立新文件 |
“ab”(二进制追加) | 向二进制文件尾部添加数据 | 出错 |
“r+”(读写,打开写) | 为了读和写,打开一个文本文件 | 出错 |
“w+”(只写) | 为了读和写,新建一个文本文件 | 建立新文件 |
“a+”(追加) | 为了读和写,打开一个文本文件 | 出错 |
“rb+”(二进制只读) | 为了读和写,打开一个二进制文件 | 出错 |
“wb+”(二进制只写)) | 为了读和写,新建一个二进制文件 | 建立新文件 |
“ab+”(二进制追加) | 为了读和写,打开一个二进制文件 | 出错 |
使用文件方式说明
- r 方式打开: 只读方式打开,
主要用于向计算机输入
而不能用作该文件输出数据,该文件必须已存在,不存在报错
。 - w 方式打开: 写入方式打开,只能
向该文件写数据
,而不能用来向计算机输入数据。如果原来不存在该文件
,则在打开文件前新建该文件。如果存在该文件
,则先删除原有文件,再新建
一个新文件。 - a 方式打开: 追加写入方式,在
文件末尾添加新数据,即不删除原有的文件
。打开文件时,文件的读写位置自动移到文档末尾。
- r+ w+ a+方式打开: 这三种方式打开的文件即可以用来输入数据,也可以用来写入数据。使用方式和上面相同,最大的不同就是
可读可写
。 - 错误提示: 如果 fopen 打开文件时出错,会返回一个错误信息,指针为 NULL,所以如果 fopen 出错的时候,可以使用 NULL 来检测。
1 | if((fp==fopen("filename","r"))=NULL){ |
- 版本警告: 有些 C 编译系统不支持 r+ w+ 等操作,或者操作为 rw wr ar 等等,所以要注意。
- 回车和换行符: 从 ASCII 文件读入字符时,遇到回车换行符,系统会转成一个换行符存储。输出时,会转换成回车和换行符两个字符。
二进制文件
由于和内存中保持一直,所以不存在转换,所以不存在这个问题。
- 流文件: 程序中可以使用三种流文件:
标准输入流、标准输出流和标准出错输出流
,它们分别从终端输入、输出和显示报错信息,所以不需要用 fopen 打开它们。这也是我们之前一直从终端输入输出却不用 fopen 打开的原因。
fclose 函数关闭文件
在使用完一个文件后,我们建议要立刻将该文件关闭,防止它被误使用。我们说的关闭,主要是:
- 撤销文件信息区
- 撤销文件缓冲区
- 文件指针变量不在指向该文件
也就是,文件指针变量与文件分离。
一般形式是:
fclose (文件指针);
例如:
1 | fclose (file1); |
把指向文件的 file1 指针关闭后,指针和文件之间就不再有联系了。
不关闭文件会怎样?
如果不关闭文件,可能会丢失数据!还记的写文件的时候的过程吗?
二进制数据 -> 文件缓冲区 -> 文件
其实缓冲区的内容,是等待二进制数据充满之后,才正式保存的文件的。如果没充满,就结束程序了,那么其实文件的数据会丢失一部分,因为还在缓冲区。
fclose 函数,就解决了这个问题,fclose 函数主动把缓冲区中的数据输出到磁盘文件中,然后才撤销文件信息区,避免了该问题。
注意
文件操作完成后,请务必带上 fclose 关闭该文件
关闭成功
如果关闭文件成功,fclose 也会返回一个值
成功 则返回0,失败则返回 EOF(-1)
我们可以用条件判断语句检测
1 | if(fclose(file1)==0){ |
尾巴
这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。