将数据放在文件中是一种相对安全的存储方式。在学习C语言时,我们可以通过使用文件操作来对文件进行读写和更改。
什么是文件
磁盘盘上的文件是文件。在程序设计中,一般讨论两种文件:程序文件和数据文件(从功能角度)。文件名的结构为:文件路径+文件名主干+文件后缀。例如:c:\code\test.txt
程序文件:包括程序文件(.c)、目标文件(.o)和可执行程序(.exe)
数据文件:数据文件的内容不一定是程序,而是程序运行时读写的数据
有时会把信息输出到磁盘上,需要时再从磁盘读取到内存进行使用,这里处理的就是磁盘上的文件。
文件类型
按文件存储数据的类型来分类,文件可以分为文本文件和二进制文件。
文本文件:文本文件用来存放文本,是以ASCII字符的形式存储的文件
二进制文件:二进制信息不加转换输出到外存,存储该信息的文件就是二进制文件
文件缓冲区
文件缓冲区是内存中的一块区域,包括输入缓冲区和输出缓冲区。输入/输出信息时,将文件缓冲区放满后再输入/输出到磁盘/屏幕上。
文件的打开和关闭
文件指针
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存储文件的相关信息(文件的名字,文件状态及文件当前的位置等)。这些信息保存在一个结构体变量FILE中。每打开一个文件,系统就会创建一个对应的FILE变量,并自动填写其中内容。文件的操作路径为:文件指针->文件信息区->文件。
文件的打开和关闭
在对文件读写之前需要先打开文件;完成读写操作后需要关闭文件。在打开文件的同时,会返回一个FILE*指向该文件,相当于建立了指针和文件的关系。若打开文件失败,则fopen返回NULL。
用fopen来打开文件,用fclose关闭文件。
fopen:
FILE *fopen( const char
*filename, const char *mode
);
注意检验文件是否打开成功。
fclose:
int fclose( FILE *stream );
用于释放文件资源。注意关闭文件后将pf置空,避免产生野指针。
文件读写
文件的顺序读写
功能 |
函数名 |
适用于 |
字符输入函数 |
fgetc |
所有输入流 |
字符输出函数 |
fputc |
所有输出流 |
文本行输入函数 |
fgets |
所有输入流 |
文本行输出函数 |
fputs |
所有输出流 |
格式化输入函数 |
fscanf |
所有输入流 |
格式化输出函数 |
fprintf |
所有输出流 |
二进制输入 |
fread |
文件 |
二进制输出 |
fwrite |
文件 |
从标准输入/输出流读写数据:
fscanf/fprintf/sscanf和scanf/printf/sprintf的对比
scanf : 从标准输入流中读取数据
fscanf :从所有流中读取数据
printf:写入数据到标准输出流
fprintf:写入数据到所有流中
sprintf:将格式化的信息转化为string格式写入到指定位置
sscanf:将string格式的数据读出
文件的随机读写
每次文件读写结束时,文件指针都会向后偏移1,为了更灵活地对文件进行读写,有时需要对文件指针进行操作。
fseek()
int fseek( FILE *stream, long offset, int origin );
将文件指针移动到指定位置。其中origin表示起始位置,包括三种选择。
SEEK_CUR:从当前位置开始偏移
SEEK_END:从文件末尾开始偏移
SEEK_SET:从文件起始位置开始偏移
ftell()
long ftell( FILE *stream );
计算当前指针位置相对于文件起始位置的偏移量
rewind()
void rewind( FILE *stream );
将文件指针恢复到起始位置
文件的结束
文件的结束判定
当文件读取结束时,有两种可能原因:
- 文件读取到末尾
- 文件读取遇到错误
对于文本文件和二进制文件分别有不同的判断文件读取是否结束的方法。
文本文件
1.判断fgetc(int ch)的返回值是否为EOF
2.判断fgets的返回值是否为NULL
二进制文件
判断fread的返回值是否小于实际要读的个数
判断文件读取结束的原因
为了确保程序继续正常运行,有时需要对文件结束读取的原因进行判断。一般用 feof() 和 ferror() 判断文件结束读取的原因。
feof()
int feof( FILE *stream );
判断文件是否到达末尾。若到达文件末尾返回一个非 0 值,否则返回 0。
ferror()
int ferror( FILE *stream );
判断文件读取是否遇到错误。若遇到错误返回一个非 0 值,否则返回 0。