深度剖析:数据
深度剖析:递归
深度剖析:结构体
深度剖析:动态内存管理
深度剖析:文件操作
深度剖析:预处理
文件是当今计算机系统十分重要的部分。文件用于存储程序、文档、数据、图形、照片、视频、书信、表格和许多其他种类的信息。作为程序员,必须会编写创建文件和从文件读写数据的程序。本文将介绍相关的内容。
通讯录需要一块可以保存信息的空间,当需要时可随时调取
我们常用的通讯录在使用之后可以将信息进行存储,当我们再次需要调取信息时,里面的内容依然存在,这时我们就需要一个文件去存储相关信息。文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
I/O 的两个级别 (即处理文件访问的两个级别) :
标准 I/O 的优势:
在程序设计中,我们一般谈的文件有两种:程序文件、数据文件
程序文件: 包括源程序文件(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(windows环境后缀为.exe)。
数据文件: 文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
根据数据的组织形式,数据文件被称为文本文件或者二进制文件
文本文件: 如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。
小明男11111某某大学
二进制文件: 数据在内存中以二进制的形式存储,如果不加转换的输出到外存,就是二进制文件。

ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。

缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”
FILE *pf;//文件指针变量
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态及 文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统声明的,取名FILE。
不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关 心细节。
定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文 件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。
FILE *fopen("文件名.后缀", "打开方式");
返回一个指针,需要判断是否为空指针
int fclose(文件地址);
关闭成功返回0,否则返回EOF(-1)
FILE *P_File = fopen("文件名.后缀", "打开方式");
if (P_File == NULL) {
perror("打开文件失败:");
}
fclose(P_File);
| 文件使用方式 | 含义 | 如果指定文件不存在 |
|---|---|---|
| “r”(只读) | 为了输入数据,打开一个已经存在的文本文件 | 出错 |
| “w”(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件 |
| “a”(追加) | 向文本文件尾添加数据 | 出错 |
| “rb”(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
| “wb”(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
| “ab”(追加) | 向一个二进制文件尾添加数据 | 出错 |
| “r+”(读写) | 为了读和写,打开一个文本文件 | 出错 |
| “w+”(读写) | 为了读和写,建议一个新的文件 | 建立一个新的文件 |
| “a+”(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
| “rb+”(读写) | 为了读和写打开一个二进制文件 | 出错 |
| “wb+”(读写) | 为了读和写,新建一个新的二进制文件 | 建立一个新的文件 |
| “ab+”(读写) | 打开一个二进制文件,在文件尾进行读和写 | 建立一个新的文件 |
int fputc(int , FILE *stream);
向文件写入数据(从末尾开始写入)
fputc('1', P_File);
fputc('2', P_File);
fputc('3', P_File);
int fgetc(FILE *stream);
向文件读数据(从开头开始按顺序读,读一次向后走一格)
- 读取结束返回EOF
- 正常读取返回ASCII码值
int ret = fgetc(P_File);
printf("%c", ret);
int fputs(const char *str, File *stream);
向文件写入数据(从末尾开始写入)
fputs("abcdef\n", P_File);
fputs("123456\n", P_File);
char *fgets(char *str, int n, FILE *stream)
读取数 n 包括
'/0'的位置,所以最多读 n - 1 个
fgets(arr, 5, P_File);
printf("%s\n", arr);
fgets(arr, 20, P_File);
printf("%s\n", arr);
int fprintf(File *stream, 后面与printf一致);
向文件写入数据(从末尾开始写入)
fprintf(P_File, "%s\n", "hello world!");
int fscanf(File *stream, 后面与scanf一致);
读取(从开始位置)
fscanf(P_File, "%s", arr);
printf("%s\n", arr);
int fwrite(要写入的元素的地址, 每个元素的大小, 元素的数量, File *stream);
以二进制的方式写入(字符串以二进制和文本写入结果一样)
fwrite(arr, sizeof(char), 20, P_File);
int fread(要读取的元素的地址, 每个元素的大小, 元素的数量, File *stream);
返回读取到的完整元素的个数,如果读取到的个数 < 实际要读的个数,则为最后一次读取
fread(arr, sizeof(char), 20, P_File);
int fseek("文件", 偏移量, 偏移的起始位置);
确定书写的位置
- SEEK_CUR - 当前位置
- SEEK_SET - 开头位置
- SEEK_END - 结尾位置(当指向结尾时,偏移量只能为负)
int fwind("文件");
让文件指针回到起始位置
int feof(文件地址);
是判断读取失败结束,还是遇到文件结尾结束
- 文本文件读取是否结束,判断返回值是否为EOF,或者是否为NULL等。每个函数有每个特定的结束标志。
- 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
对于大多数的程序而言,文件的相关操作必不可少。标准 I/O 包自动创建输入和输出缓冲区以加快数据传输。多种输入输出方式使得程序更加灵活便捷,大大提高了程序的效率,同时也兼具良好的可移植性。