C语言具有操作电脑上的文件的功能。我们可以通过这个功能实现数据的存储。C程序中涉及到的所有变量和数据,都会随着程序终止被销毁。但是如果将一些数据写入文件,我们就能把它固定下来。
一、流的概念
C语言中对于文件的操作,是将一个文件抽象成流。我们在控制台输入的数据,这些东西其实进入了标准输入流(stdin)。在控制台输出的数据,则来自标准输出流(stdout)。除此之外,程序在运行时发生的错误,这些错误信息进入了标准错误流(stderr)。
所谓的流,其实本质上是文件指针FILE*。
二、操作文件的基本流程
FILE *pf = fopen("./data.txt","r");
这个语句规定了文件的打开方式,并将打开的文件抽象成文件指针。
我们以“r”,只读的方式打开了一个文件,文件路径为当前目录下的data.txt。
注意,如果打开的文件不存在或者打开失败,会返回一个空指针。这时应该判断指针是否为空。
char arr[20];
fgets(arr,20,pf);
在这个栗子里,我们从文本流pf中读取了字节的数据,并将其存储到arr数组中。
fgets是众多操作文本流的函数之一。常见函数还有
fgetc:读取一个字符
fputc:写入一个字符
fputs:写入一个字符串
fread:以二进制形式读入
fwrite:以二进制形式写入
fscanf:从文本流读取数据
fprintf:向文本流输出数据
如果我们对于文本的操作结束了,应该关闭文件
fclose(pf);
关闭文件后,pf的指向就失效了,应该将其置为NULL。
文件的读取和写入其实不是直接进行的,数据是暂时放在缓冲区里。然后从缓冲区慢慢地把数据读取和写入。关闭文件则有把缓冲区里的数据强制写入的功能。这样就可以避免数据在缓冲区内没有写入带来的损失。
注意:在写入模式下,新写入的内容会覆盖旧内容。如果不想覆盖,可以将fopen中的mode修改为“a”,这样就能在文件后面添加新内容了。或者调用fseek函数移动光标位置,将光标位置移动到上次编辑的地方。
三、文件类型
前面我们提到二进制文本操作函数fread、fwrite。为什么要有二进制的区分呢。我们的数据可能包含视频、图片、音频等多媒体数据,这些数据是不能直接被编译器识别出来的。将他们转化为二进制,就可以通过C语言对这些特殊数据进行操作了。
如果想要读写二进制文件,可以把fopen函数传入的mode参数改为“wb”或“rb”。其中b是binary二进制的意思。
四、文件指针
文件指针可以看成一种类似于光标的东西,它指向我们目前操作的文本位置。初始状态下光标的位置为0,表示从文本流开头开始操作。
对光标的操作,有三个常用函数:1.fseek用来修改光标指向
2.ftell用来查询当前光标指向
3.rewind用来将光标重置到初始位置
五、错误处理
我们可以使用feof和ferror进行错误处理。这两个函数都是传入一个文件指针作为参数。不同的是如果发生了文件操作错误,ferror(pf)的值为true,否则为false。而如果遇到了文件末尾,feof(pf)的值为true,否则为false。
六、扩展
有这么一组函数:
printf scanf
fprintf fscanf
sprintf sscanf
其中第一组是对标准流进行的操作,而第二组可以对所有文本流进行操作。
第三组则是对给定字符串的格式化输入输出。