本章重点
- 为什么运用文件
- 什么是文件
- 文件的翻开和封闭
- 文件的次序读写
- 文件的随机读写
- 文本文件和二进制文件
- 文件读取完毕的断定
- 文件缓冲区 正文开端
1. 为什么运用文件
咱们前面学习结构体时,写了通讯录的程序,当通讯录运转起来的时分,能够给通讯录中增加、删去数据,此刻数据是寄存在内存中,当程序退出的时分,通讯录中的数据自然就不存在了,等下次运转通讯 录程序的时分,数据又得从头录入,假如运用这样的通讯录就很难过。
咱们在想既然是通讯录就应该把信息记录下来,只有咱们自己选择删去数据的时分,数据才不复存在。 这就触及到了数据耐久化的问题,咱们一般数据耐久化的办法有,把数据寄存在磁盘文件、寄存到数据库等办法。
运用文件咱们能够将数据直接寄存在电脑的硬盘上,做到了数据的耐久化。
2. 什么是文件
磁盘上的文件是文件。 但是在程序设计中,咱们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度来分类的)。
2.1 程序文件
程序文件包含: 源程序文件(后缀为.c)、方针文件(windows环境后缀为.obj)、可执行程序(windows环境 后缀为.exe)。
2.2 数据文件
文件的内容纷歧定是程序,而是程序运转时读写的数据,比如程序运转需求从中读取数据的文件,或许输出内容的文件。
本章讨论的是数据文件。 在以前各章所处理数据的输入输出都是以终端为目标的,即从终端的键盘输入数据,运转成果显示到显示器上。 其实有时分咱们会把信息输出到磁盘上,当需求的时分再从磁盘上把数据读取到内存中运用,这儿处理的便是磁盘上文件。
2.3 文件名
一个文件要有一个唯一的文件标识,以便用户识别和引用。 文件名包含3部分:文件路径+文件名主干+文件后缀 例如: c:\code\test.txt 为了便利起见,文件标识常被称为文件名。
3. 文件的翻开和封闭
3.1 文件指针
缓冲文件体系中,要害的概念是“文件类型指针”,简称“文件指针”。
每个被运用的文件都在内存中开辟了一个相应的文件信息区,用来寄存文件的相关信息(如文件的名字,文件状况及文件当时的方位等)。这些信息是保存在一个结构体变量中的。该结构体类型是有体系声明的,取名FILE。
例如,VS2013编译环境提供的 stdio.h 头文件中有以下的文件类型申明:
struct _iobuf {
char* _ptr;
int _cnt;
char* _base;
int _flag;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
};
typedef struct _iobuf FILE; //FILE为体系声明的结构体类型
意思就相当于,FILE这个结构体类型,创立了一个结构体变量,这个结构体变量的内存空间里边寄存的便是某个文件相关的信息。
不同的C编译器的FILE类型包含的内容不完全相同,但是大同小异。 每逢翻开一个文件的时分,体系会依据文件的状况主动创立一个FILE结构类型的变量,并填充其中的信息, 运用者不用关怀细节。 一般都是经过一个FILE的指针来维护这个FILE结构的变量,这样运用起来愈加便利。
下面咱们能够创立一个FILE的指针变量:
FILE* pf;//文件指针变量
定义pf是一个指向FILE类型数据的指针变量。能够使pf指向某个文件的文件信息区(是一个结构体变量)。经过该文件信息区中的信息就能够拜访该文件。也便是说,经过文件指针变量能够找到与它相关的文件。 比如:
3.2 文件的翻开和封闭
文件在读写之前应该先翻开文件,在运用完毕之后应该封闭文件。 在编写程序的时分,在翻开文件的同时,都会回来一个FILE*
的指针变量指向该文件,也相当于建立了指针和文件的联系。
ANSIC 规则运用fopen函数来翻开文件,fclose来封闭文件。
//翻开文件
FILE* fopen(const char* filename, const char* mode);
//回来一个FILE类型的指针,两个参数分别为:(文件名,运用文件的办法)
//封闭文件
int fclose(FILE* stream);
//回来一个整型数据,参数为一个待封闭的文件指针
翻开办法如下:
示例代码:
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#include <stdio.h>
int main()
{
FILE* pFile;
pFile = fopen("myfile.txt", "w");//仅”写"文件
//文件操作
if (pFile != NULL)
{
perror("pFile");
}
fclose(pFile); //封闭文件
pFile = NULL;
return 0;
}
输出成果:
4. 文件的次序读写
由于咱们写程序时是在内存中写的,而文件又在硬盘上,当咱们把文件里的数据读到内存中去的动作叫做输入(读取),把程序中的数据写到文件里边或许放到硬盘上的动作叫做写入(输出)。
下图为在咱们读写文件时会用到的各种函数
4.1 fputc字符输出函数
写入文件,例如向文件中输入一些字符:
fputc函数为向指定的文件中输入一个字符,榜首个参数为输入的字符,第二个参数为文件指针,回来值为字符的ASCLL值。
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#include <stdio.h>
int main()
{
FILE* pf;
pf = fopen("E:\\test\\test2.23.txt", "w");//仅“写"文件
//文件操作
if (pf == NULL)
{
perror("pf");
return 1;
}
//写文件
fputc('b', pf);
fputc('i', pf);
fputc('t', pf);
fclose(pf); //封闭文件
pf = NULL;
return 0;
}
‘b”i”t’写入文件时,也是按照次序来写入的,因而叫做文件的次序读写. 当fputc消失时,输入文件里的值也会消失:
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#include <stdio.h>
int main()
{
FILE* pf;
pf = fopen("E:\\test\\test2.23.txt", "w");//仅”写"文件
//文件操作
if (pf == NULL)
{
perror("pf");
return 1;
}
//写文件
//fputc('b', pf);
//fputc('i', pf);
//fputc('t', pf);
fclose(pf); //封闭文件
pf = NULL;
return 0;
}
能够看到文件的巨细又变为了0KB
4.2 fgetc字符输入函数
读取文件,例如读取文件中的字符数据:
fgetc函数为从指定的文件中读取一个字符,若读取正常,则会回来字符的ASCLL值,若读取失利,则会回来EOF(符号常量,其值为-1),fgetc每运用一次,文件的方位指针就会主动向后移动一位。
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#include <stdio.h>
int main()
{
FILE* pf;
pf = fopen("E:\\test\\test2.23.txt", "r");//仅“读"文件
//翻开文件,"r"为仅读取
if (pf == NULL)
{
perror("pf");
return 1;
}
//写文件
int ret = fgetc(pf);//一次
//从文件中读取一个字符
printf("%c\n", ret);
//打印读取的字符
ret = fgetc(pf); //两次
printf("%c\n", ret);
ret = fgetc(pf); //三次
printf("%c\n", ret);
//每读取完一个字符后,再读取时主动读取下一个字符
fclose(pf); //封闭文件
pf = NULL;
return 0;
}
文件内容:
输出成果:
当fgetc读取完毕或许读取过错时则会回来EOF(-1):
4.3 fputs文本行输出函数
按行输入文件:
fputs为向指定的文件中写入字符串,不主动写入字符串完毕符号符‘\0’。 成功写入一个字符串后,文件的方位指针会主动后移,函数回来值为 非负整数;输入过错则回来 EOF (符号常量,其值为-1)
注:换行要体现在代码中
按行输入时无换行符\n:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
FILE* pf;
pf=fopen("E:\\test\\test2.23.txt", "w");//仅”写"文件
//写文件--按行来写
if (pf == NULL)
{
perror("pf");//若pf为空指针,则输出过错原因
return 1;
}
fputs("abcdef", pf);//留意:换行的话要体现在代码中
fputs("ghijkllmn", pf);
fclose(pf);
pf = NULL;
return 0;
}
文件中的内容: 按行输入时有换行符\n:
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#include <stdio.h>
int main()
{
FILE* pf;
pf=fopen("E:\\test\\test2.23.txt", "w");//仅“写"文件
//写文件--按行来写
if (pf == NULL)
{
perror("pf");//若pf为空指针,则输出过错原因
return 1;
}
fputs("abcdef\n", pf);//留意:换行的话要体现在代码中
fputs("ghijkllmn", pf);
fclose(pf);
pf = NULL;
return 0;
}
文件中的内容:
4.4 fgets文本行输入函数
按行读取文件:
fgets函数的作用是从指定的文件中读取num个字符,num是最多能读取的字符个数,但是真实读取到的字符个数为num-1,由于最终要留一个方位给’\0’,最终读取到的内容会存储到字符指针变量str所指向的内存空间中。
示例代码如下:
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#include <stdio.h>
int main()
{
char str[50] = { 0 };
FILE* pf;
pf=fopen("E:\\test\\test2.23.txt", "r");//仅”读"文件
//读取文件
if (pf == NULL)
{
perror("pf");//若pf为空指针,则输出过错原因
return 1;
}
fgets(str, 5, pf);//只读取4个字符的内容
printf("%s\n", str);
fgets(str, 3, pf);//只读取2个字符的内容
printf("%s\n", str);
fclose(pf);
pf = NULL;
return 0;
}
文件内容:
输出成果: 为了澄清fgets函数的原理,咱们在文件内容不变的根底大将代码做了一些修改:
//输出成果是什么?
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#include <stdio.h>
int main()
{
char str[50] ="xxxxxxxxxxxxxxxxxxxxxxx";
FILE* pf;
pf=fopen("E:\\test\\test2.23.txt", "r");//仅“读"文件
//读取文件
if (pf == NULL)
{
perror("pf");//若pf为空指针,则输出过错原因
return 1;
}
fgets(str, 5, pf);//只读取4个字符的内容
printf("%s\n", str);
fgets(str, 1, pf);//读取的内容是什么?
printf("%s\n", str);
fgets(str, 8, pf);
printf("%s\n", str);
fclose(pf);
pf = NULL;
return 0;
}
输出成果: 开端调试:
fgets榜首次运用时: fgets第2次运用时: fgets第三次运用时:
经过str字符数组的内容的改变状况,咱们能够得知,fgets函数在运用时,会把读到的字符数存储到咱们所创立的字符数组中去, 并且会在末尾带上一个’\0′, 不仅如此,后一次读取的内容在存储时会将前一次读取的内容从榜首个字符开端覆盖掉, 当fgets中的参数num为1时,就会将\0存储在字符数组中,因而在咱们输出在屏幕上时就会什么内容都没有; 当num为0时,不会将任何内容存储在字符数组中。
4.5 fprintf格局化输出函数
format表明格局(%s、%d等等),后边的”…”表明可变参数(一个或许多个参数,参数的个数能够改变),fprintf和printf相比仅仅多了一个FILE*stream
罢了。
示例代码如下:
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#include<stdio.h>
typedef struct Student
{
char Name[20]; //名字
int Age; //年纪
float High; //身高
}S;
int main()
{
S s = { "张三",18,177.5f };
FILE* pf = fopen("E:\\test\\test2.23.txt", "w");//仅”写"文件
//对格局化的内容进行读取(输入)文件
if (pf == NULL)
{
perror("pf");
return 1;//函数非正常停止
}
fprintf(pf, "%s %d %f", s.Name, s.Age, s.High);
fclose(pf);
pf = NULL;
return 0;
}
输出成果:
文件内容:
4.6 fscanf格局化输入函数
跟fprintf相同,format表明格局(%s、%d等等),后边的”…”表明可变参数(一个或许多个参数,参数的个数能够改变),fscanf和scanf相比也仅仅多了一个
FILE*stream
罢了。
示例代码如下:
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#include<stdio.h>
typedef struct Student
{
char Name[20]; //名字
int Age; //年纪
float High; //身高
}S;
int main()
{
S s = { 0 };
FILE* pf = fopen("E:\\test\\test2.23.txt", "r");//仅"读"文件
//对格局化的内容进行读取(输入)文件
if (pf == NULL)
{
perror("pf");
return 1;//函数非正常停止
}
fscanf(pf, "%s%d%f", s.Name, &(s.Age), &(s.High));
//读取的内容就相当于在屏幕上输入的内容
printf("%s %d %f", s.Name, s.Age, s.High);
//输出读取的内容
fclose(pf);
pf = NULL;
return 0;
}
文件内容:
输出成果:
4.7 fwrite、fread二进制输出、输入函数
fwrite的作用是写内容到指定文件中去,void* buffer的意思是指向所写内容的指针,size_t size表明要写的内容有多少字节,size_t count表明要写入的以上一个参数为单位的元素个数,FILE* stream表明文件指针,回来值是表明读取元素的个数。
fread的作用是读取指定文件里的内容,且榜首个参数ptr表明盛放内容的首地址. 第二个参数size表明每个元素的巨细,单位仍是字节. 第三个参数表明要读取的元素个数. 第四个参数stream表明的是文件指针,即从哪个文件中读取. 回来值则是表明读取元素的个数。
示例代码如下:
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#include<stdio.h>
typedef struct Student
{
char Name[20]; //名字
int Age; //年纪
float High; //身高
}S;
int main()
{
S s = {"张三",18,177.5};
FILE* pf;
pf = fopen("E:\\test\\test2.23.txt", "w");//仅"写"文件
if (pf == NULL)
{
perror("pf");
return 1;
}
fwrite(&s, sizeof(s), 1, pf);
fclose(pf);
pf = NULL;
return 0;
}
文件内容: 这是啥?此刻咱们发现文件中的部分内容咱们并不认识,乃至能够说是一串乱码,但是咱们假如用fread函数来读取的话,是否能够读出来咱们原本想写入的数呢?
示例代码如下:
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#define _CRT_SECURE_NO_WARNINGS
/* fopen fclose example */
#include<stdio.h>
typedef struct Student
{
char Name[20]; //名字
int Age; //年纪
float High; //身高
}S;
int main()
{
S s = {0};
FILE* pf;
pf = fopen("E:\\test\\test2.23.txt", "r");//仅"读"文件
if (pf == NULL)
{
perror("pf");
return 1;
}
fread(&s, sizeof(s), 1, pf);//读取文件
printf("%s %d %f", s.Name, s.Age, s.High);
fclose(pf);
pf = NULL;
return 0;
}
文件内容: 输出成果: 由此可见,fread和fwrite函数平常应该放在一同运用。
4.8 对比一组函数
scanf / fscanf / sscanf
printf / fprintf / sprintf
scanf–针对标准输入的格局化的输入句子–stdin
fscanf–针对一切输入流的格局化的输入句子–stdin/文件
sscanf–对一个字符串读出格局化的数据
参数str为要读取数据的字符串;format为用户指定的格局;”…”为变量,用来保存读取到的数据。【回来值】成功则回来参数数目,失利则回来-1。
printf–针对标准输出的格局化输出句子–stdout
fprintf–针对一切输出流的格局化输出句子-stdout/文件
sprintf–把一个格局化的数据转化为字符串
跟sscanf相同,参数str为要读取数据的字符串;format为用户指定的格局;”…”为变量,用来保存读取到的数据。【回来值】成功则回来参数数目,失利则回来-1。
sprintf示例代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
typedef struct Student
{
char Name[15];//名字
int Age; //年纪
float High; //身高
}S;
int main()
{
S s = { "张三",18,177.5 };
char buf[100] = { 0 };
sprintf(buf, "%s %d %f", s.Name, s.Age, s.High);
//sprintf(将s内的数据整组成字符串并存到buf字符数组中,格局,指定的数据);
printf("%s\n", buf);
//打印 buf 字符数组的内容,s内的内容将直接作为字符串打印出来
return 0;
}
输出成果:
那么如何将这个字符串数据还原呢?
sscanf示例代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
typedef struct Student
{
char Name[15];//名字
int Age; //年纪
float High; //身高
}S;
int main()
{
S s = { "张三",18,177.5 };
char buf[100] = { 0 };
S tmp = { 0 };
sprintf(buf, "%s %d %f", s.Name, s.Age, s.High);
//sprintf--将格局化的数据转化为字符串
//sprintf(将s内的数据整组成字符串并存到buf字符数组中,格局,指定的数据);
printf("%s\n", buf);
//打印buf字符数组的内容,s内的内容将直接作为字符串打印出来
sscanf(buf, "%s %d %f", tmp.Name, &(tmp.Age), &(tmp.High));
//sscanf-从字符串中读取格局话数据
printf("%s %d %f\n", tmp.Name, tmp.Age, tmp.High);
//打印读取的数据
return 0;
}
输出成果:
5. 文件的随机读写
在前面的学习中,咱们知道那些定位文件的指针在时间发生改变,比如说在你读取一次今后就会主动指向下一个要读取的内容,这样的办法有一定的局限性,没办法让咱们想读哪儿就读哪儿,那么有没有什么局限性更小的办法呢?接下来咱们就来看看文件的随机读写。
5.1 fseek
fseek:依据文件指针的方位和偏移量来定位文件指针便是移动文件指针到咱们想要的当地去。
榜首个参数是文件指针,第二个参数offset是偏移量(确认偏移量时要考虑开端偏移的开始方位,有三种开始方位,榜首个SEEK_SET是从文件开始方位开端偏移,第二个SEEK_CUR是从当时文件指针的方位开端偏移,第三个SEEK_END是从文件末尾开端偏移,正数向左,负数向右,偏移的单位为字节),第三个参数origin是开始方位。
示例代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
//文件内容:zhangsan
FILE* pf;
pf = fopen("E:\\test\\test2.23.txt", "r");
if (pf == NULL)
{
perror("pf");
return 1;
}
int ch = fgetc(pf); //榜首次
printf("%c\n", ch); //z
fseek(pf, 2, SEEK_CUR);
//文件指针从z处(文件指针现在所指的方位)向右偏移两个字节(a处)
ch = fgetc(pf); //第2次
//文件指针主动指向下一位(n处)
printf("%c\n", ch); //n
ch = fgetc(pf); //第三次
//文件指针主动指向下一位(g处)
printf("%c\n", ch); //g
fseek(pf, -2, SEEK_END);
//从末尾n处向左偏移两个字节(s处)
ch = fgetc(pf); //第四次
//文件指针主动指向下一位(a处)
printf("%c\n", ch); //a
fclose(pf);
pf = NULL;
return 0;
}
文件内容:
输出成果:
5.2 ftell
ftell的作用便是告诉咱们当时文件指针相对于开始方位的偏移量是多少,其参数为文件指针,回来值为偏移量的值。
示例代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
//文件内容:zhangsan
FILE* pf;
pf = fopen("E:\\test\\test2.23.txt", "r");
if (pf == NULL)
{
perror("pf");
return 1;
}
int ch = fgetc(pf); //榜首次
printf("%c\n", ch); //z
fseek(pf, 2, SEEK_CUR);
//文件指针从z处(文件指针现在所指的方位)向右偏移两个字节(a处)
int n = ftell(pf); //现在方位距开始方位的偏移量
printf("%d\n", n); //3
fclose(pf);
pf = NULL;
return 0;
}
输出成果:
5.3 rewind
rewind的作用让现在文件指针的方位回到文件的开始方位,参数为文件指针。
示例代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
//文件内容:zhangsan
FILE* pf;
pf = fopen("E:\\test\\test2.23.txt", "r");
if (pf == NULL)
{
perror("pf");
return 1;
}
int ch = fgetc(pf); //榜首次
printf("%c\n", ch); //z
fseek(pf, 2, SEEK_CUR);
//文件指针从z处(文件指针现在所指的方位)向右偏移两个字节(a处)
rewind(pf); //回到开始方位
ch = fgetc(pf);
printf("%c", ch); //z
fclose(pf);
pf = NULL;
return 0;
}
输出成果:
6. 文本文件和二进制文件
依据数据的组织方式,数据文件被称为文本文件或许二进制文件。
数据在内存中以二进制的方式存储,假如不加转化的输出到外存(文件)中,便是二进制文件。
假如要求在外存上以ASCII码的方式存储,则需求在存储前转化。以ASCII字符的方式存储的文件便是文本文件。
一个数据在内存中是怎么存储的呢?
字符一律以ASCII方式存储,数值型数据既能够用ASCII方式存储,也能够运用二进制方式存储。 如整数10000,假如以ASCII码的方式输出到磁盘,则磁盘中占用5个字节(每个字符一个字节),而二进制方式输出,则在磁盘上只占4个字节(VS2013测验)。
图示:
翻开二进制文件: 二进制文件:
7. 文件读取完毕的断定
7.1 被过错运用的feof
紧记:在文件读取过程中,不能用feof函数的回来值直接用来判别文件是否完毕。 而是应用于当文件读取完毕的时分,判别是读取失利完毕,仍是遇到文件尾完毕。
fgetc函数在读取完毕的时分,会回来EOF 正常读取的时分,回来的是读取到的字符的ASCLL码值
fgets函数在读取完毕的时分,会回来NULL 正常读取的时分,回来寄存字符串的空间开始地址
fread函数在读取的时分,回来的是实践读取到完好元素的个数 假如发现读取到的完好的元素的个数小于指定的元素个数,就会当作最终一次读取
例如,文件内容复制:
//将test2.23的内容复制一份,生成test2.24
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
FILE* pfread = fopen("E:\\test\\test2.23.txt", "r");
if (pfread == NULL)
{
return 1;
}
FILE* pfwrite = fopen("E:\\test\\test2.24.txt", "w");
if (pfwrite == NULL)
{
fclose(pfread);
pfread = NULL;
return 1;
}
//文件翻开成功
//读写文件
int ch = 0;
while ((ch = fgetc(pfread))!= EOF)
{
//写文件
fputc(ch, pfwrite);
}
//封闭文件
fclose(pfread);
pfread = NULL;
fclose(pfwrite);
pfwrite = NULL;
return 0;
}
代码运转前:
代码运转后:
成功复制:
8. 文件缓冲区
ANSIC 标准采用缓冲文件体系处理的数据文件的,所谓缓冲文件体系是指体系主动地在内存中为程序中每一个正在运用的文件开辟一块文件缓冲区。从内存向硬盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一同送到硬盘上。假如从硬盘向计算机读入数据,则从硬盘文件中读取数据输入到内存缓冲区(充溢缓冲区),然后再从缓冲区逐一地将数据送到程序数据区(程序变量等)。缓冲区的巨细依据C编译体系决议的。
打个比如,假如当一个教师预备上课时,有许多学生陆陆续续的发问题,不断打断教师讲课,那么课堂功率就会明显下降;若教师说,当一个人攒够10个问题今后才能发问,那么一方面会一定程度上约束同学发问的次数,另一方面也会进步课堂的功率,缓冲区也是这个道理。
例如:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
//VS2022 WIN11环境测验
int main()
{
FILE* pf = fopen("E:\\test\\test2.23.txt", "w");
fputs("abcdef", pf);
//先将代码放在输出缓冲区
printf("睡眠10秒-已经写数据了,翻开test.txt文件,发现文件没有内容\n");
Sleep(10000);
printf("改写缓冲区\n");
fflush(pf);//改写缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
printf("再睡眠10秒-此刻,再次翻开test.txt文件,文件有内容了\n");
Sleep(10000);
fclose(pf);
//注:fclose在封闭文件的时分,也会改写缓冲区
pf = NULL;
return 0;
}
缓冲区改写前:
缓冲区改写后:
这儿能够得出一个定论:
由于有缓冲区的存在,C语言在操作文件的时分,需求做改写缓冲区或许在文件操作完毕的时分封闭文 件。 假如不做,可能导致读写文件的问题
本篇的内容到这儿就完毕了,假如你觉得对你多少有点协助的话能够点赞支撑一波哦,咱们下次再见!