文章重点
(1)为什么使用文件(2)是么是文件(3)文件的打开和关闭(4)文件的顺序读写(5)文件的随机读写(6)文本文件和二进制文件(7)文件读取结束的判定(8)文件缓冲区
一 为什么使用文件
我们想要把内容记录下来,选择删除数据的时候,数据才会不存在,这是关于数据持久化的问题,一般数据持久化的方法有:把数据存放在磁盘文件、存放在数据库等。
使用文件我们可以把文件直接存放到电脑的硬盘上,做到数据的持久化。
二 什么是文件
磁盘上的文件是文件;程序设计中,从文件的功能来分,文件分为数据文件和程序文件。
2.1 程序文件
源程序文件(后缀为 .c )、 目标文件( windows 环境后缀为 .obj )、 可执行程序( windows 环境
后缀为 .exe )
2.2 数据文件
文件的内容不一定是程序,而是程序运行时读写的数据。比如:程序运行时从中读取的文件或者输出内容的文件。(这篇文章讨论的是数据文件)
(在以前写的文章中,数据的输入输出都是以终端为对象的,就是从终端的键盘输入数据,运行结果显示到显示器上。 但是我们有时候,我们会把信息输出到磁盘上,有需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上的文件。)
2.3 文件名
文件要有一个唯一的文件标识。文件名包括三部分:文件路径+文件名主干+文件后缀。(例如:C:\code\test.txt。C:\code\就是文件路径,test就是文件名主干,.txt就是文件后缀)(为了方便起见,文件标识称为文件名)
三 文件的打开和关闭
使用文件需要打开文件,不使用要关闭文件。
3.1 文件指针
缓冲文件系统中,关键的概念是 “ 文件类型指针 ” ,简称 “ 文件指针 ”
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统 声明的,取名 FILE .
例如, VS2013 编译环境提供的 stdio.h 头文件中有以下的文件类型申明:
1. struct _iobuf { 2. char* _ptr; 3. int _cnt; 4. char* _base; 5. int _flag; 6. int _file; 7. int _charbuf; 8. int _bufsiz; 9. char* _tmpfname; 10. }; 11. typedef struct _iobuf FIRE;
不同的 C 编译器的 FILE 类型包含的内容不完全相同,但是大同小异。
每当打开一个文件的时候,系统会根据文件的情况自动创建一个 FILE 结构的变量,并填充其中的信息,使用者不必关心细节。 一般都是通过一个 FILE 的指针来维护这个 FILE 结构的变量,这样使用起来更加方便。
下面我们可以创建一个 FILE* 的指针变量 :
FILE * pf ; // 文件指针变量
定义 pf 是一个指向 FILE 类型数据的指针变量。可以使 pf 指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说, 通过文件指针变量能够找到与它关联 的文件。(返回的是FIRE*的指针变量,指向文件信息区的起始地址 )
3.2 文件的打开和关闭
文件在读写之前应该先 打开文件 ,在使用结束之后应该 关闭文件 。
在编写程序的时候,在打开文件的同时,都会返回一个 FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。(返回的是FIRE*的指针变量,指向文件信息区的起始地址 )
// 打开文件
FILE * fopen ( const char * filename , const char * mode );
// 关闭文件
int fclose ( FILE * stream);
1. #include <stdio.h> 2. int main() 3. { 4. FILE* pf = fopen("test.txt", "w");//默认的路径是test.c的路径, 5. //""注意是双引号 6. return 0; 7. }
下图,test.txt和test.c在同一个路径下
1. #include <stdio.h> 2. #include <string.h> 3. #include <errno.h> 4. int main() 5. { 6. //打开文件,读文件 7. FILE* pf = fopen("test.txt", "r");//默认的路径是test.c的路径, 8. //""注意是双引号 9. if (pf == NULL) 10. { 11. printf("%s\n", strerror(errno));//如果没有这个文件的话,就会报错,读文件 12. return 0; 13. } 14. //关闭文件 15. fclose(pf); 16. pf = NULL;//这个指针变量不再用的时候,置为空指针 17. return 0; 18. }
"r"(只读),为了输入数据,打开一个已经存在的文本文件,文件不存在的话,就会报错(返回空指针)。
"w"(只写),为了输出文件,打开一个文本文件,文件不存在的话,建立一个新的文件。(如果没有写文件路径,那么默认在操作文件的路径下,如果文件存在的话,打开的时候,会把里面的内容全部删除)
内存中的数据输出到屏幕或者文件中是输出,反之就是输入
四 文件的顺序读写
fgetc,fputc,注意对象是字符。
fputc
一个一个的写:
1. #include <stdio.h> 2. #include <string.h> 3. #include <errno.h> 4. 5. int main() 6. { 7. FILE* pf = fopen("date.txt", "w"); 8. if (pf == NULL) 9. { 10. printf("%s\n", strerror(errno)); 11. } 12. fputc('a', pf); 13. fputc('b', pf); 14. fputc('c', pf); 15. 16. fclose(pf); 17. pf = NULL; 18. return 0; 19. }
1. #include <stdio.h> 2. #include <string.h> 3. #include <errno.h> 4. 5. int main() 6. { 7. FILE* pf = fopen("date.txt", "w"); 8. if (pf == NULL) 9. { 10. printf("%s\n", strerror(errno)); 11. } 12. //fputc('a', pf); 13. //fputc('b', pf); 14. //fputc('c', pf); 15. 16. char ch = 0; 17. for (ch = 'a'; ch <= 'z'; ch++) 18. { 19. fputc(ch, pf); 20. } 21. fclose(pf); 22. pf = NULL; 23. return 0; 24. }
内容在文件中显示出来就得打开文件关闭文件,为什么屏幕就不用呢,因为在C语言中,程序运行起来,就会打开三个流:stdio—标准输入流,stdout—标准输出流(在屏幕中显示),stderr—标准错误流(这三个都是FILE*类型的)
所以,上个代码,把pf改成stdout,就可以把内容输出到屏幕上