🌳🌲🌱本文已收录至:C语言——梦想系列
更多知识尽在此专栏中!
🎉🎉🎉欢迎点赞、收藏、关注 🎉🎉🎉
🌳前言
** 文件——是我们生活中必不可缺的一部分,优秀的文件管理能使我们工作效率更高,比如上学时的点名册、平时记账的手账本、电脑中存储数据的各种文件夹等。数据构成文件,文件成就数据,因此我们需要学习C语言中的各种文件操作,使数据能够做到持久化存储。**
图片来源:百度图片
🌳正文
文件操作涉及到的内容还是比较多的,大致可分为三个问题:是什么? 怎么用? 要注意什么? 从这三个问题可以衍生出很多问题,其中怎么用是内容最丰富的版块,让我们直接进入正题吧。
🌲关于文件
🌱什么是文件?
如上图所示,这就是文件,不过这是传统的纸质文件。在我们电脑中的都是电子文件夹,存储的都是电子文件,比如数字、图片、文档等,这些数据都是存储在我们电脑的硬盘上的,只要硬盘没坏,那么这些数据随时随地都能找到,而且方便检索。在程序设计中,我们一般将文件分为两种:程序文件与数据文件(从文件功能的角度分类),本文主要介绍的是数据文件。
程序文件
包括源程序文件,比如我们的 .c 文件;目标文件,经过预编译、编译、汇编后生成的目标文件,后缀为 .o ,对其进行链接后,就能生成可执行程序;当然最后一种就是可执行程序文件,后缀为.exe
数据文件
就像上图一样,主要存储的是各种数据信息,数据文件的职能是能让程序读取到数据,以及能够对其写入数据,这些数据是能够持久化存储的。
🌱文件有什么用?
电脑C盘中存储的各种信息
文件可以保存数据,使数据能做到持久化存储。文件可以使我们的操作更为合理,比如现在写的这篇博客,本质就是一个文件,不过是存储在服务器上的文件(数据)。电子文件的最大特点就是易于检索了,这也正是电脑的优点之一。至于C语言中的文件可以用于保存程序运行所产生的数据,比如通讯录系统,可以将联系人信息保存到文件中,现在的程序设计数据一般都是存储在数据库中,毕竟本地文件夹安全性还是比较低。
🌱文件的格式是什么?
所有文件都有唯一的标识符,标识符可以分为三部分:文件路径+文件名主干+文件后缀,比如存储在我电脑中的VS文件标识符为:
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE
为了方便称呼,我们一般将其称为文件名,比如 devenv.exe 就是一个典型的程序文件
🌲使用文件
🌱文件指针
文件是一个庞大的集合体,类似于结构体,不过更为复杂,因此在C语言中有一个专门的指针 文件类型指针,简称为 文件指针 用来指向文件首地址。系统会将文件规范化,当使用文件时,系统会在内存中开辟一个对应的文件信息区,这个信息区中包括了文件的各种信息(文件名、文件状态、文件位置等),如果对应信息缺失,系统会自动补齐。前面说过,文件类似于结构体,因此整个文件信息是保存在一个庞大的结构体中的,为了与传统结构体区分开,专门创建了FILE这种特殊的指针,即*文件指针。
因为VS2019将其分的太细了,这里不好演示,但知道FILE** **这个东西本质是个结构体就行了
🌱文件的打开和关闭
文件得先打开,才能关闭,最好跟动态内存管理一样,有申请就要有释放,成对出现更为安全。先来说说打开吧!
🪴文件打开
文件打开用的是** fopen 这个函数,fopen 的作用是从一个文件中以某种方式打开文件,返回类型是 FILE 即打开文件的起始地址,因此我们需要用一个* FILE*** 类型的指针来接收。
**注意:文件打开后,要对文件指针进行判断,如果指针为空,说明文件打开失败,此时要报错,并终止后续操作 **
if (NULL == fp)
{
//报错函数,说明此文件打开失败
perror("fopen::test.txt!");
return 1;//错误结束
}
🪴目标文件
有两种形式,一种是绝对地址,另一种是相对地址
绝对地址
即唯一路径,使用绝对地址访问文件时,文件可以在电脑中的任意位置,前提是地址要合法。绝对位置的文件标识符必须全,即文件路径+文件名主干+文件名后缀。
比如 C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE
注意:
**使用绝对路径时,需要在每个 \ 前额外加一个 \ 原因很简单,单个 \ 与其他字符结合,可能会变成一个转义字符,因此需要两个 \ 来表示一个 \ **
**如果是 Mac 就不需要担心这个问题,因为它用的是 / **
//绝对,指此地址是唯一的,能通过这个地址找到唯一的文件
FILE* fp = fopen(" C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\Common7\\IDE", "w");
相对位置
此时的路径是固定的,一般和当前源文件处于同一位置,相对嘛,就是相对于当前程序文件。相对位置只需要文件名主干+文件后缀就行了 。
比如 devenv.exe ,此时存储位置相对于上面的绝对地址,位于同一目录下
//相对,指在当前工程文件内的文件
FILE* fp = fopen("test.txt", "w");
🪴**打开方式 **
文件打开方式有很多种,比如只读、只写、读+、二进制写等……
值得注意的是当我们通过读的方式打开文件时,如果目标文件不存在,那么打开就会失败;但如果是通过写的方式打开文件时,如果文件不存在,会自动创建一个目标文件。
下面来演示下用写的方式打开文件,然后文件不存在,自动创建文件的情况:
注意:这种是文件的标准使用方式,即先打开,然后判断是否打开失败,如果失败就报错,否则就可以使用文件,最后再关闭文件
//文件创建,通过程序创建
int main()
{
//可以利用只读的特性:没有就会自己创建
//这里是相对路径
FILE* fp = fopen("test.txt", "w");//打开
if (NULL == fp)
{
//报错函数,说明此文件打开失败
perror("fopen::test.txt!");
return 1;//错误结束
}
//进行文件操作……//
fclose(fp);//关闭
fp = NULL;//置空
return 0;
}
注意:
- 这个特点很好用,但也很致命,因为每次写文件,都相当于在覆盖文件,假如我们想对原文进行追加,就需要创建原来的数据,再创建新数据,然后一起写入文件中。其实面对这种场景,C语言还提供了另一种文件打开方式 追加 "a",下面就是各种打开指令的集合表。
文件打开指令含义如果目标文件不存在"r" 只读打开一个文件,只能对这个文件进行读取操作打开失败,报错"w" 只写打开一个文件,只能对这个文件进行写入操作建立目标文件"a" 追加向文件末尾处添加数据建立目标文件"rb" 只读打开二进制文件,只能对其进行二进制读取打开失败,报错"wb" 只写打开二进制文件,只能对其进行二进制写入建立目标文件"ab" 追加向二进制文件末尾处添加数据追加失败,报错"r+" 读写打开一个文件,可以进行读取和写入操作打开失败,报错"w+" 读写打开一个文件,可以进行读取和写入操作建立目标文件"a+" 读写对文件末尾处进行读取和写入操作建立目标文件"rb+" 读写打开二进制文件,可以进行二进制读取和写入打开失败,报错"wb+" 读写打开二进制文件,可以进行二进制读取和写入建立目标文件"ab+" 读写对二进制文件末尾处进行读取和写入操作建立目标文件
🪴文件关闭
文件关闭用到的是** fclose** 这个函数,fclose 就比较简单了,只需要一个参数—文件指针(FILE),然后就能关闭这个文件指针所指向的文件,感觉有点像* free,功能强大,使用方便。同 free 一样,fclose** 关闭文件后,也需要将指针(文件指针)置空,避免出现野指针。
fclose(fp);//关闭
fp = NULL;//置空
🌲顺序读写
🌱输入、输出流
在介绍文件读写操作前,需要先说明一下C语言中“流”(format)的概念。假设将数据看作水流,那么它就有两个关键部分:从哪里流出(源头)、流入哪里(终点),其中流出可以看作输出,流入可以看作输入。C语言中有三种流:标准输入输出流、文件输入输出流、二进制输入输出流(实际使用时用前两种流,第三种的目标流一般为文件)。
🪴标准输入输出流
标准输入输出流(I/O)包括标准输入流(stdin)—从键盘输入、标准输出流(stdout)—从屏幕输出、标准错误流(strerr)—从屏幕输出,任何一个C程序,只要运行起来都会默认打开以上三个流,比如我们常用的** scanf、printf就是基于标准输入输出流而运行的**,这也正是二者需要键盘、屏幕的原因。
🪴文件输入输出流
顾名思义,文件输入输出流所依赖的载体为文件,无论是输入还是输出数据,都是在文件上进行的,因此它的对象类型为FILE* ,文件输入输出流可以使用所有输入输出流函数,比如fputc、fprintf、fscanf等,使用时只需要加上目标流类型就行了。
🪴二进制输入输出流
二进制输入输出流主要适用于文件操作,对文件进行二进制数据的读取和写入,所以二进制输入输出一般用在文件操作中。二进制只有0、1这两个数,因此如果我们使用二进制输出流对某个文件进行写入,文件中存储的信息就变成了一串二进制数(可以使用二进制文件查看器观察),如果用普通文本的形式查看此文件,会得到一串乱码。二进制输入输出流有fwrite、fread这两个函数。
注意:
- printf、scanf、gets等这种不需要指定目标流的函数,设计时就已经规定好了,它们是标准输入输出流函数。而fprintf、fscanf、fgets等这些面向所有输入输出流的函数更为原始,需要用户使用时根据具体情况选择目标流,所以这些函数也能实现标准输入输出流函数的功能,只需要把目标流写成 stdin(输入)、stdout(输出)就行了。下面是各种输入输出函数的集合表:
功能函数名适用于(目标流)进行单字符的输入fgetc 所有输入流 进行单字符的输出fputc所有输出流文本行输入函数(读取一行数据)fgets所有输入流文本行输出函数(写入一行数据)fputs所有输出流格式化输入函数fscanf所有输入流格式化输出函数fprintf所有输出流二进制输入函数fread文件输入流二进制输出函数fwrite文件输出流
注意:为了方便函数的介绍,接下来会先介绍写入(输出),再介绍读取(输入)函数
🌱fputc 与 fgetc
** fputc 对文件进行单字符的写入,fgetc **读取文件中的单字符
🪴fputc
//文件读写之逐字符写 //因为没有数据,所以我们先写再读 int main() { //打开 FILE* fp = fopen("test.txt", "w"); if (NULL == fp) { perror("fopen::test.txt!"); return 1; } //进行操作 char* pc = "abcdef123"; //逐字符写入 while (*pc) { fputc(*pc, fp);//逐字符放 pc++; } //关闭 fclose(fp); fp = NULL; return 0; }
🪴fgetc
//文件读写之逐字符读 int main() { FILE* fp = fopen("test.txt", "r"); if (NULL == fp) { perror("fopen::test.txt!"); return 1; } //逐字符读取 int ch = 0;//需要用整型,因为EOF是-1 while ((ch = fgetc(fp)) != EOF) { //逐字符读取后,赋给字符变量ch,然后打印 printf("%c", ch); } //关闭 fclose(fp); fp = NULL; return 0; }
**注意: **
- 在读取或写入字符串时,可以通过特定的条件结束读写。比如写入:可以通过字符串自带的结束标志 \0 结束写入;读取:可以通过fgetc的返回值进行判读,如果返回 -1(EOF) 就说明数据已经读取完了。
- *单纯写文本数据时,要使用指令 "w" ;单纯读数据时,要使用指令 "r" ,指令与操作一定要匹配上*,不然就会发生意想不到的错误
🌱fputs 与 fgets
** fputs** 对文件进行一行数据的写入,fgets 是读取文件中的一行数据
🪴fputs
//文件读写之行写 int main() { FILE* fp = fopen("test.txt", "w"); if (NULL == fp) { perror("fopen::test.txt"); return 1; } char* pc = "这是由标准输入输出流写入的数据"; fputs(pc, fp);//行写入 fclose(fp); fp = NULL; return 0; }
🪴fgets
//文件读写之行读 int main() { FILE* fp = fopen("test.txt", "r"); if (NULL == fp) { perror("fopen::test.txt"); return 1; } char tmp[30] = "0"; fgets(tmp, sizeof(tmp), fp);//行读取 printf("%s\n", tmp); fclose(fp); fp = NULL; return 0; }
注意:
- *行写入时,要确保写入的是字符串数据,传参数时要传地址;行读取时,需要设定待读取数据的数量,一般是跟待存储空间大小相匹配。如果行读取结束,有两种情况:***1、因无法读取数据而结束 **** ****2、因读取到文件末尾而结束 **
- 单纯写文本数据时,要使用指令** "w"**** ;单纯读数据时,要使用指令 ****"r" **
🌱fprintf 与 fscanf
** fprintf** 是对文本进行格式化数据的写入,fscanf 是将文本中的数据进行格式化读取
🪴fprintf
//按照文件流格式化写入 struct S { char name[20]; int age; float score; }a = { "张三",20,88.8f }; int main() { FILE* fp = fopen("test.txt", "w"); if (NULL == fp) { perror("fopen::test.txt"); return 1; } fprintf(fp, "%s %d %.2f", a.name, a.age, a.score);//适用于所有流的格式化输入输出函数 fclose(fp); fp = NULL; return 0; }
🪴fscanf
//按照文件流格式化读取 struct S { char name[20]; int age; float score; }tmp; int main() { FILE* fp = fopen("test.txt", "r"); if (NULL == fp) { perror("fopen::test.txt"); return 1; } fscanf(fp, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score));//适用于所有流的格式化输入输出函数 printf("%s %d %.2f\n", tmp.name, tmp.age, tmp.score); fclose(fp); fp = NULL; return 0; }
🪴延申:sprintf 和 scanf
除了**fprintf / fscanf **和 printf / scanf 这两组格式化输入输出外,还存在另一组格式化输入输出函数:sprintf / sscanf
简单介绍一下,sprintf****是把格式化的数据按照一定的格式转换为字符串,相反的,**sscanf **就是从字符串中按照一定格式读取出格式化的数据
sprintf 和** sscanf 可以把结构体中的数据打包成一个字符串,也可以对某个字符串进行拆分。这个东西在我们生活中有应用,比如当我们登录账号时,会把账号、密码这个结构体打包成一串字符串,交给后端处理,当然有个更高级的名词:序列化与反序列化**。
注意:
- *printf 输出家族返回的是*实际写入(输出)的字符总数(包括转义字符),而 scanf 输入家族返回的是实际读取(输入)的元素个数*。举个栗子,字符串 abc ,输出返回 3,输入返回 1,因为此时的字符串视为一个元素。*
- *单纯写文本数据时,要使用指令 "w" ;单纯读*数据时,要使用指令 ****"r" **
🌱fwrite 与 fread
** fwrite** 是对文件进行二进制数据的写入,fread 是以二进制的形式读取文件中的数据
🪴fwrite
//文件读写之二进制写入 struct S { char name[20]; int age; float score; }a = { "张三",20,88.8f }; int main() { //把a中的数据写到文件中 FILE* fp = fopen("test.txt", "wb"); if (NULL == fp) { perror("fopen::test.txt"); return 1; } //二进制的写文件 fwrite(&a, sizeof(a), 1, fp); fclose(fp); fp = NULL; return 0; }
🪴fread
//文件读写之二进制读取 struct S { char name[20]; int age; float score; }tmp; int main() { //把文件中的数据读取到tmp中 FILE* fp = fopen("test.txt", "rb"); if (NULL == fp) { perror("fopen::test.txt"); return 1; } fread(&tmp, sizeof(tmp), 1, fp); printf("%s %d %.2f\n", tmp.name, tmp.age, tmp.score); fclose(fp); fp = NULL; return 0; }
注意:
- 当我们使用二进制写入数据到文件时,如果是以文本的方式打开,只能看懂字符串部分,数字部分是看不懂的,我们可以通过VS中的二进制编辑器,来观察其中的数据。
- 单纯写二进制数据时,要使用指令 "wb" ;单纯读二进制数据时,要使用指令** "rb" **
🌲随机读写
随机读写函数,需要配合上面的输入输出函数使用,所谓的随机读写,是指通过改变文件指针的偏移量,来写入或读取数据。介绍三个和随机读取有关的函数:fseek 改变文件指针偏移量、ftell 查看当前文件指针的偏移量、rewind 使文件指针复原至起始位置。
🌱fseek
//fseek,文件指针偏移量 int main() { FILE* fp = fopen("test.txt", "w"); if (NULL == fp) { perror("fopen::test.txt"); return 1; } char* pc = "abc"; fseek(fp, 20, SEEK_SET);//从起点往后偏移 fputs(pc, fp); fclose(fp); fp = NULL; return 0; }
🌱ftell
//ftell,返回当前文件指针偏移信息 int main() { FILE* fp = fopen("test.txt", "r"); if (NULL == fp) { perror(fp); return 1; } printf("当前文件指针偏移量为:%d\n", ftell(fp)); fseek(fp, 20, SEEK_SET);//向后偏移20 printf("经过fseek设置后的文件指针偏移量为:%d\n", ftell(fp)); fclose(fp); fp = NULL; return 0; }
🌱**rewind **
//rewind,使文件指针恢复至原位置 int main() { FILE* fp = fopen("test.txt", "r"); if (NULL == fp) { perror("fopen::test.txt"); return 1; } fseek(fp, 20, SEEK_SET);//先让文件指针向后偏移20 printf("当前文件指针偏移量为:%d\n", ftell(fp)); rewind(fp);//使文件指针恢复至起始位置 printf("经过恢复后的文件指针偏移量为:%d\n", ftell(fp)); return 0; }
🌱fseek、ftell、rewind 三合一
//fseek、ftell、rewind三合一 //假设文件中存储数据为abcdef int main() { FILE* fp = fopen("test.txt", "r"); if (NULL == fp) { perror("fopen::test.txt"); return 1; } printf("现在文件中内容为abcdef,我们要依次取出e、b、d\n"); fseek(fp, -2, SEEK_END);//从后往前偏移 printf("先取出字符%c\n", fgetc(fp)); rewind(fp);//还原至起始位置 fseek(fp, 1, SEEK_SET);//从前往后偏移 printf("再取出字符%c\n", fgetc(fp)); fseek(fp, 1, SEEK_CUR);//从当前位置向后偏移 printf("最后再取出字符%c\n", fgetc(fp)); fclose(fp); fp = NULL; return 0; }
注意:
- 每进行一次文件输入输出操作,文件指针都会向后移动一位。比如上面的三合一, 当我们读取到字符 'b' 后,文件指针向后移动一位,指向字符 'c' ,此时只需要把文件指针向后偏移一位****,就能愉快的读取到字符 'd' 了。
🌲文本文件与二进制文件
🌱文本文件
文本文件指以ASCII码(文本方式)存储的数据,原始数据机器能直接看懂,将内存中的数据对应ASCII码解码存储后,我们人类也能看懂,举个栗子,在记事本中写的文本,就是文本文件
🌱二进制文件
二进制文件是将数据编译后转成二进制形式,然后直接存储的文件,这种文件机器能秒懂,读取效率很高(因为不需要转译),但二进制一般人是看不懂的,部分二进制数据也无法通过ASCII码解码为正确的数据,因此强行输出二进制文件,极有可能会得到乱码。比如将上面的那段话通过二进制形式写入文件中,可以看到除字符类型数外,其他类型的数据变成了乱码。
下图为上面的二进制文件在内存中以二进制形式存储的样子,显示为十六进制(节省空间),实际为二进制。
🌱注意
- 如果待读取的文件中存储的是二进制数据,就需要使用 二进制读取 "rb" 的形式读取数据;反之如果想写入二进制数据,就需要用 二进制写入 "wb" ,无论是二进制还是普通文本,计算机都能读懂,只是我们看不得罢了。小技巧:可以使用二进制存储重要数据,这样外行人一时半会也理解不了。
🌲文件使用注意事项
🌱被错误使用的feof
很多人在写C语言课设的时候(学生信息管理系统、通讯录系统等),会通过 feof****来判断文件是否读取结束,这是一种错误的用法,因为** feof** 的作用是判断当前文件读取结束原因的,如果是因为读取到了末尾而结束,**feof(fp) 就为真;除了这个以外,还有另一个文件读取结算原因判断函数,ferror ,当**** ferror(fp) *为真时,说明此时发生了读取异常,并非正常结束,我们可以通过这两个报错函数来判断文件读取结束的真正原因。*
char arr[100] = "0";
fgets(arr, sizeof(arr), fp);
printf("%s\n", arr);
int n = 0;
if ((n = feof(fp)))
printf("End by EOF\n");
if (ferror(fp))
printf("End by IO Error\n");
🌱文件读取结束原因判断
既然** feof** 不是用来判断读取是否结束的,那说明存在其他判断方法,其实答案就是函数设计中,前辈在设计函数时已经考虑好了,比如** fgetc** 没有读取到数据会返回EOF,fgets 没有读取到数据会返回NULL,fscanf 可以通过其返回的实际读取元素个数进行判断,fread 可以通过返回值与指定读取的元素数比较。每种读取函数都有属于的自己的判断方法,比如下面这两个例子:
🪴对文本数据进行读取
//读取错误信息判断
//1.文本文件版,假设文件内已有信息,为abcdef
int main()
{
FILE* fp = fopen("test.txt", "r");
if (NULL == fp)
{
perror("fopen::test.txt");
return 1;
}
int ch = 0;//接收读取的数据,要用整型,因为EOF为-1
while ((ch = fgetc(fp)) != EOF)
{
printf("%c", ch);
}
//判断是为何结束
if (feof(fp))
printf("\nEnd by EOF(因读到文件末尾而结束)\n");
else if (ferror(fp))
printf("\nEnd by IO(因中途读取失败而结束)\n");
fclose(fp);
fp = NULL;
return 0;
}
🪴对二进制文件进行读取
//2.二进制文件版
enum { SIZE = 5 };//相当于宏定义
int main()
{
double a[SIZE] = { 1.1,2.2,3.3,4.4,5.5 };
//首先把五个浮点数以二进制的形式,写入文件中
FILE* fp = fopen("testFoBin.txt", "wb");
if (NULL == fp)
{
perror(fp);
return 1;
}
fwrite(&a, sizeof(*a), SIZE, fp);
fclose(fp);//写入完成,关闭文件
double b[SIZE] = { 0.0 };
//现在以二进制的形式读取数据
fp = fopen("testFoBin.txt", "rb");
int size = fread(&b, sizeof(*b), SIZE, fp);
if (size == SIZE)
{
printf("No Error!\n");
int i = 0;
while (i < size)
printf("%.2lf ", b[i++]);
}
else
{
if (feof(fp))
printf("\nError by EOF\n");
else if(ferror(fp))
printf("\nError by IO\n");
}
fclose(fp);
fp = NULL;
return 0;
}
🌱文件缓冲区
ANSIC 标准定义了“缓冲文件系统”这个概念,所谓缓冲文件系统是指系统自动地在内存中为程序
中每一个正在使用的文件开辟一块“文件缓冲区”。无论是读取还是写入数据时,都会先将数据送入文件缓冲区,等文件缓冲区****装满或遇到刷新指令后,数据才会被读取(写入)到目标空间中。文件缓冲区的大小是由编译器决定的。
🪴验证文件缓冲区是否存在
我们可以利用睡眠函数** Sleep** 来使程序暂停,此时数据还没有被写入文件中,仍然位于缓冲区;之后再手动刷新缓冲区,数据此时会被推送至文件中。
//文件缓冲区 #include<windows.h> int main() { //打开文件 FILE* fp = fopen("test.txt", "w"); if (NULL == fp) { perror(fp); return 1; } char* ps = "测试文件缓冲区"; fputs(ps, fp);//先将数据写到缓冲区中 printf("数据现在已经在缓冲区里面了,但还没有推送到文件中\n"); printf("程序睡眠10秒,10秒后刷新缓冲区\n"); Sleep(10000);//睡眠函数,单位是毫秒 fflush(fp); printf("现在缓冲区已经刷新,数据已经写入文件中了\n"); Sleep(10000); //关闭文件,当文件关闭时,缓冲区也会被刷新 fclose(fp); fp = NULL; return 0; }
** 可以看到文件缓冲区是真实存在的。**
注意:
- fclose 关闭文件后,会自动刷新缓冲区,数据能够推送至文件
- 当程序运行结束后,缓冲区也会被自动刷新
- scanf 遇到 \n 也会触发缓冲区刷新,另外如果其在读取字符型数据时,遇到空白字符(空格、TAB键)也会触发缓冲区的刷新
🌳总结
** 以上就是C语言文件操作的所有内容了,从文件的打开到文件的关闭,中间可以进行多种操作,构造出巧妙的数据。当然前提是我们得学会文件的相关操作,可以巧记为单字符读写、行读写、格式化读写和二进制读写,无论是那种操作,都需要和对应的文件操作指令匹配上;关于随机读写,记住那三个偏移量函数就行了;最后需要对文件缓冲区有一定的理解,确保数据能成功推送至文件内。总之,文件操作的学习可以宣布毕业了。**
** 如果你觉得本文写的还不错的话,期待留下一个小小的赞👍,你的支持是我分享的最大动力!**
** 如果本文有不足或错误的地方,随时欢迎指出,我会在第一时间改正**
相关文章推荐
C语言进阶——动态内存管理
C语言进阶——自定义类型
C语言进阶——指针进阶试题讲解(万字长文详解)
版权归原作者 Yohifo 所有, 如有侵权,请联系我们删除。