一:为什么使用文件
首先,在我们进行写完代码之后,似乎每一次当我们运行完成程序后,关闭程序时,都会将我们输入的数据销毁掉。但在实际生活中里面的每一个程序或者APP都会将我们之前所使用的数据保存下来。那这些数据是保存到哪里的呢? 答案显而易见—— 使用文件来保存数据。
二:什么是文件
当了解了为什么使用文件后,再来探讨什么是文件。
文件的分类
1.程序文件
程序文件储存的是程序
程序文件包括:源程序文件(后缀为.c),目标文件(Windows环境中,后缀为 .obj),可执行程序(Windows环境中国,后缀为 .exe)。
2.数据文件
数据文件储存的是数据
数据为程序运行时所使用的数据。
其中我们重点讨论:数据文件
在初学C语言时,我们都是运用终端(键盘)直接将数据输入到程序中,运行结果显示到屏幕(显示器)上。
但当我们需要储存数据时,就要将数据储存到磁盘上,当需要再次使用时,再从磁盘上把数据读取到内存中。磁盘就是储存文件的位置。
三:文件的打开和关闭
文件名
文件名就是文件唯一的文件标识,是用于用户的方便识别和使用。
使用文件名就类似我们自己拥有的身份证号码,是唯一的且可以用于识别人的基本信息。
文件名包含3个部分 文件路径+文件名主干+文件后缀
例如: c:\用户\test.txt
文件指针
在缓存文件系统中,里面的关键概念为“文件类型指针”, 简称“文件指针”。
每一个 被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(文件名, 文件路径,文件的状态等)。这些信息是保存在一个结构体变量中的,该结构体由系统声明,取名为
**FILE
随着技术的发展,文件FLIE结构体里的内容一直在变化,上图是某一时间,某一编译器定义的FILE结构体。
每一种C编译器里的FILE类型的内容虽然会不一样,但大同小异。
每当我们打开文件时,系统会根据文件的情况自动创建一个FILE结构的变量,并填充里面的信息。使用者不用特别关心里面的内容。
并且,一般都是通过FILE指针来管理FLIE结构里的变量。
创建一个FILE的变量
FILE* pf;//文件类型变量
定义pf是一个指向FILE类型的数据的指针变量,可以使pf指向某一个文件的文件信息区(一个结构体变量)。通过这个文件信息区里的信息就可以访问到该文件。也就是,可以通过文件指针变量来找到与其对于的文件。
类似于上图
文件的打开和关闭
所使用的函数为 fopen 和 fclose
fopen:FILE * fopen ( const char * filename, const char * mode )
fclose:int fclose ( FILE * stream )
首先先来介绍 fopen
对于文件的打开和关闭类似于动态内存的开辟和释放,打开和关闭,开辟和释放都是要同时存在的。
FILE * fopen ( const char * filename, const char * mode )
*filename是我们要打开文件的文件名, *mode是打开文件的方式。
注: 两者都是字符串,在使用时要用" "包括。
其中打开方式如下图
文件使用方式 | 含义 | 如果指定文件不存在 |
---|---|---|
“r”(只读) | 为了输入数据,打开一个已经存在的文本文件 | 出错 |
“w”(只写) | 为了输出数据,打开一个文本文件 | 建立一个新的文件 |
“a”(追加) | 向文本文件尾添加数据 | 建立一个新的文件 |
“rb”(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
“wb”(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
“ab”(追加) | 向一个二进制文件尾添加数据 | 出错 |
“r+”(读写) | 为了读和写,打开一个文本文件 | 出错 |
“w+”(读写) | 为了读和写,建议一个新的文件 | 建立一个新的文件 |
“a+”(读写) | 打开一个文件,在文件尾进行读写 | 建立一个新的文件 |
“rb+”(读写) | 为了读和写打开一个二进制文件 | 出错 |
“wb+”(读写) | 为了读和写,新建一个新的二进制文件 | 建立一个新的文件 |
“ab+”(读写) | 打开一个二进制文件,在文件尾进行读和写 | 建立一个新的文件 |
代码演示
#include <stdio.h>
int main()
{
//打开文件,使用"w"时,如果没有文件就会
//创建一个新文件
FILE* pf = fopen("test.txt", "w");
//判断是否打开成功
if (pf == NULL)
{
perror("fopen:");
return;
}
//在文件里写数据等
//关闭文件
fclose(pf);
//同free 需要赋NULL
pf = NULL;
return 0;
}
注:打开文件后,使用完毕时,要关闭文件。如同动态内存的开辟和释放。
四:文件的顺序读写
顺序读写所代表的含义是在从文件输入或输出时,数据时按照顺序来输入或输出的。其中,有以下代码为顺序读写时,所使用的。
如图:
功能 | 函数名 | 适用于 |
---|---|---|
字符输入函数 | fgetc | 所有输入流 |
字符输出函数 | fputc | 所有输出流 |
文本行输入函数 | fgets | 所有输入流 |
文本行输出函数 | fputs | 所有输出流 |
格式化输入函数 | fscanf | 所有输入流 |
格式化输出函数 | fprintf | 所有输出流 |
二进制输入 | fread | 文件 |
二进制输出 | fwrite | 文件 |
输入:把文件里的数据输入到程序中
输出:将程序中的数据输出到文件里。
下面来简单介绍一组函数:fgetc fputc
先来介绍fput
int fputc ( int character, FILE * stream )
fputc实现将程序里的数据输出到文件中。
character:所使用的数据
FILE * stream:流(后续介绍,这里先可以理解为文件指针)
#include <stdio.h>
int main()
{
//打开文件,使用"w"时,如果没有文件就会
//创建一个新文件
FILE* pf = fopen("test.txt", "w");//w一定要用""包括
//判断是否打开成功
if (pf == NULL)
{
perror("fopen:");
return;
}
//写文件
int i = 0;
for (i = 0; i < 26; i++)
{
fputc('A' + i, pf);
}
//关闭文件
fclose(pf);
//同free 需要赋NULL
pf = NULL;
return 0;
}
这时,我们可以进行一下步骤找到我们所做出的结果
打开test.txt文件
发现就是我们程序所输出到文件里的数据。
fgetc
int fgetc ( FILE * stream )
fgetc实现将文件里的数据输入到程序中。
注当fgetc读取失败时会返回EOF
先在工程里创建一个文件并写入一些数据
#include <stdio.h>
int main()
{
//打开文件,使用"w"时,如果没有文件就会
//创建一个新文件
FILE* pf = fopen("test2.txt", "r");//这里是读文件
//判断是否打开成功
if (pf == NULL)
{
perror("fopen:");
return;
}
//写文件
int c = 0;
while ((c = fgetc(pf)) != EOF)
{
printf("%c", c);
}
//关闭文件
fclose(pf);
//同free 需要赋NULL
pf = NULL;
return 0;
}
运行结果
这里先来简单讲解C语言的文件操作,后续还将继续介绍更深,细节的文件操作。(比如文件的使用方式,顺序读写中的函数)
谢谢大家的阅读,让我们一起努力变强吧!