前言:在使用电脑时,我们常常能看见一大堆文件,那么你知道什么是文件吗?你知道如何进行文件操作吗?在本章,将教大家一些简单的文件操作方法。
这里是目录:
1.什么是文件?
存在磁盘中的文件就是文件。
在程序设计中,一般有两种文件:程序文件、数据文件(从文件功能角度来分类)。
1.1程序文件
包括源程序文件
.c
、目标文件.obj
、可执行文件.exe
等。
1.2数据文件
文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行时需要从中读取数据的文件或者输出内容的文件。
本章讨论的是数据文件。如果想了解一些程序文件的知识的话,请看这篇博客:翻译环境和执行环境
1.3文件名
文件名包含3部分:文件路劲+文件名主干+文件后缀,例如:C:\android\text.txt
,同时,为了方便起见,文件标识常被称为文件名。
2.为什么使用文件?
常规情况下写出来的代码数据都是放在内存上的,退出程序就销毁了。想要将数据持久化,就要将数据放在磁盘上,这就是为什么电脑的盘中有那么多文件。
3.文件的打开和关闭(重点)
问:假如我们想从冰箱中拿一个西瓜,有几个步骤呢?首先需要打开冰箱门,然后从中拿出西瓜,最后再关上冰箱门。
文件的使用与这是类似的:首先要打开文件,然后对文件进行操作,最后关闭文件。
3.1文件指针的概念
想要进行文件操作,首先得知道什么是文件指针
。
缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字,文件状态以及文件当前的位置等等)。这些信息是保存在一个结构体变量中的。改结构体类型是由系统声明的,取名FILE
。
3.2fopen/fclose函数
fope:打开文件
fclose:关闭文件
fopen,fclose的使用方式和动态数组开辟中的malloc/free函数非常相似,有此基础的朋友理解起来相信会很轻松。
fopen函数
fopen函数的第一个参数为想要打开的文件,第二个参数为文件使用方式。
注意它的类型是FILE*
,并且两个参数都需要用""
括起来。
fclose函数
fclose函数相对简单,只需要输入想要关闭的文件流即可。
文件使用模式
这里的文件使用方式又是一个大家陌生的知识点,下面给大家普及几种常见的文件使用模式:
这里举个例子:方便大家明白具体该如何使用fopen和fclose函数。
#include<stdio.h>
int main()
{
//打开文件,创建一个FILE*变量,这里我设置的文件没有具体路径,默认在当前路径底下,用"w"方式打开文件
FILE* pf = fopen("text.txt", "w");
//判断文件是否创建成功,记住该格式即可。
if (pf == NULL)
{
perror("Error opening file");
}
//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
上述代码运行之后,再在当前文件目录底下查看,我们会发现多了一个text.txt的文件,双击打开文件后会发现里面什么都没有,因为我们还没有对它进行输入输出操作。
到这里,相信你们就学会了文件的打开和关闭。我们继续向下学习。
4.文件顺序读写(重中之重)
上面我们了解了文件的打开和关闭,这里将介绍它们的中间环节——文件输入输出操作。
4.1标准/文件流输入输出对比
下图1为标准输入输出图,图2为文件流输入输出图。
该类比图对于下面的顺序读写函数的理解非常有帮助。
许多人会在这里产生疑惑:比如我们想在文件中写数据,用的是fputc函数,而这与标准流中put函数的逻辑是相反的,put函数是将数据打印出来。这种时候就可以看看看看下图2.
记住:写文件——输出 ,读文件——输入
4.2顺序读写函数
下列的函数能够适用于文件流的输入输出,大体上与标准输入输出函数很相似。跟之前一样,还是带大家看几个函数的具体使用例子,便于大家了解掌握。
fputc函数
fputc函数具有两个参数,第一个为想输出的字符,第二个为文件流。
问:假如想在文件中输出26个英文字母,该怎么用fputc实现?
#include<stdio.h>
int main()
{
FILE* pf = fopen("text.txt", "w");
if (pf == NULL)
{
perror("Error opening file");
}
//实现部分
for (int i = 0; i < 26; i++)
{
fputc('a'+i, pf);
}
fclose(pf);
pf = NULL;
return 0;
}
执行代码后,我们再在当前文件路径底下打开text.txt文件,会发现文件里面显示了26个英文字母。
fgetc函数
fgetc函数只有一个参数,即将要输入的文件流。
问:刚刚我们在文件text.txt中输出了26个英文字母,该怎么读取文件输入它们呢?
#include<stdio.h>
int main()
{
FILE* pf = fopen("text.txt", "r"); //!!!因为要读取文件,所以这里文件操作方式变为''r''
if (pf == NULL)
{
perror("Error opening file");
}
for (int i = 0; i < 26; i++)
{
int ret = fgetc(pf); //fgetc返回值是int类型,所以创建一个int类型的变量接收它的返回值。
printf("%c ", ret); //打印
}
fclose(pf);
pf = NULL;
return 0;
}
代码执行后终端显示如下:上述代码我们并没有进行26个英文字母的赋值操作,而是直接从文件中读取数据
fprintf函数
适用于所有流的格式化输出函数
fprintf函数具有两个参数,第一个为文件流,第二个与标准输入函数scanf的参数一样。
使用fprintf函数时,可以先当作printf将第二个参数写出来,最后再加上第一个参数文件流。
问:怎么将一个结构体变量写到文件中?
#include<stdio.h>
struct stu //创建一个stu结构体
{
char name[10];
char sex[5];
int age;
};
int main()
{
struct stu S1 = {
"zhangsan","nan",25 };
FILE* pf = fopen("text.txt", "w"); //写文件“w”
if (pf == NULL)
{
perror("Error opening file");
}
fprintf(pf,"%s %s %d", S1.name, S1.sex, S1.age);//输出到文件中
fclose(pf);
pf = NULL;
return 0;
}
代码执行后打开文件text.txt文件显示如下:可以感觉fprintf使用起来与我们经常使用的标准输出函数printf差别不大。
fscanf函数
适用于所有流的格式化输入函数
与上面的fprintf类似,第一个参数为文件流,第二个参数与标准输入函数scanf参数一样。
问:怎么将刚刚写到文件中的结构体打印出来?相信这个问题肯定难不到看到这里的各位
#include<stdio.h>
struct stu
{
char name[10];
char sex[5];
int age;
};
int main()
{
struct stu S = {
0 }; //创建一个结构体变量
FILE* pf = fopen("text.txt", "r"); //读文件
if (pf == NULL)
{
perror("Error opening file");
}
fscanf(pf,"%s%s%d", S.name, S.sex, &(S.age)); //将文件中数据输入到内存中
printf("%s %s %d", S.name, S.sex, S.age); //打印
fclose(pf);
pf = NULL;
return 0;
}
代码执行后终端显示如下:
顺序读写函数就展示到这里了,如果各位读者对其它函数也很感兴趣的话,可以去cplusplus网站,里面对函数的介绍很详细,并且都有例子方便读者了解。
至此,文件3步骤就学完了,快去实践实践吧。
文末BB:对哪里有问题的朋友,可以在评论区留言,若哪里写的有问题,也欢迎朋友们在评论区指出,博主看到后会第一时间确定修改。最后,制作不易,如果对朋友们有帮助的话,希望能给点点赞和关注.