一文吃透C语言文件操作:打开、读写、缓冲区全解——保姆级C语言文件操作笔记,看完不懵
文章目录0.行文思路1.为什么学文件2.什么是文件2.1文件的两种分类2.2文件名3.二进制文件和文本文件4.文件的打开和关闭4.1流和标准流4.1.1流4.1.2标准流4.2文件的打开和关闭4.2.1 fopenmode的分类绝对路径与相对路径相对路径绝对路径**考虑一下斜杠写哪种格式 **4.2.2 fclose4 文件的读写4.1 顺序读写fputcfgetcfeof和ferrorfputsfgetsfprintffscanffwrite和freadsprintf和sscanf三组函数的对比4.2随机读写fseekftellrewind5.内存缓冲区fflush6.更新文件关键要点0.行文思路最开始我们介绍了为什么我们现在要学文件。在前面我们学的都是如何直接写程序但是现在我们要学会文件操作通过程序来控制文件。然后我们介绍了一下文件讲了两种文件类型二进制文件和文本文件对于文件有三种操作打开关闭读写我们先从简单的讲起先讲打开和关闭然后我们讲读写读写分为好多种有顺序读写随机读写后面我们知道要完整的完成“打开读写关闭”这些操作还需要对缓冲区有一定的认识然后我们介绍了一下文件缓冲区的概念又讲了一下怎样对缓冲区进行操作1.为什么学文件写的程序的数据是储存在电脑的内存中是暂时保存。如果程序退出内存就会回收数据可能丢失。下次再次运行程序是看不到上次的数据的——为了进行持久化的保存所以要使用文件2.什么是文件保存在磁盘/硬盘上的东西2.1文件的两种分类程序文件源程序文件在写C语言代码时的.C文件目标文件在Windows中是.obj文件可执行的程序.exe文件数据文件——本章讨论的主要内容不一定是程序而是程序运行时读写的数据程序运行需要从中读取数据的文件程序运行需要输出内容的文件2.2文件名电脑中的文件名是唯一的文件路径文件主干文件后缀比如C:\Users\15212\Desktop\code\动态内存管理.md3.二进制文件和文本文件在内存中以二进制形式直接存储不加转换的 输入到外存的文件中,就是二进制文件在外存上以ASCII码值的形式存储则需要在存储前转换——以ASCII字符的形式存储的文件就是文本文件数据在文件中是怎么存储的字符都是 ASCII码值数字可以用ASCII码值也可以使用二进制形式对于10000这个整数如果以ASCII码值的形式输出到磁盘则会根据有5个数字被拆分成5个字节一个字节存储一个码值存的码值分别是49,48,48,48,48的二进制数一共是五个字节如果将1万以二进制的形式存储则是四个字节一个int一个具体的写入文件的示例#define_CRT_SECURE_NO_WARNINGS1#includestdio.hintmain(){inta10000;FILE*pffopen(test.txt,wb);///打开文件以二进制的形式写fwrite(a,4,1,pf);///二进制的形式写到文件中,一个数据,四个字节,写到pf关联的文件中fclose(pf);pfNULL;return0;}下图表示运行成功了点开这个看看发现的确写入了一个文件用记事本打开会出现下面的内容 , 因为是以二进制形式存储的所以我们看不懂我们现在可以点击原文件然后点击添加现有项目添加这个文件后点击这个文件右击鼠标然后选择以二进制的形式打开为什么这不是我们存储的10000呢回忆一下10000的二进制其实是00000000 00000000 00100111 00010000转化成16进制就是00 00 27 10在VS上以小端的形式存储,就是10 27 00 004.文件的打开和关闭下面内容的铺开都和这张图有关首先我们是想通过一个程序来 对文件进行操作打开文件时如果想对文件进行操作需要创建一个流这个流对应一个文件指针类型是FILE*。这就是文件的地址后续对此文件进行操作也需要通过这个地址操作时数据会先放在缓存中在后面通过流对文件进行读/写文件是一种容器相当于储存空间一个瓶子或盒子。我们想象给瓶子灌水取水的过程第一步打开瓶子第二步灌水或取水第三步关闭瓶子。所以如果我们想使用文件的话我们就要学会对文件进行打开和关闭还有读写4.1流和标准流4.1.1流想要通过程序控制各种设备如果对每一个设备对不同设备分别编写各自的程序操作比较麻烦。为了方便对各种设备进行比较统一的操作我们抽象出了流的概念。可以把流想象成流淌着字符的河。C语言程序针对文件画面键盘等等的数据的输入输出操作都需要通过这条河。我们想要向流里写数据或者从流中读取数据 都要先打开流然后再操作。4.1.2标准流但好像我们之间从来没有打开过流每次都是直接就开始写程序了。这是因为C语言程序在启动的时候就已经默认打开了3个流。他们的类型都是FILE通常称为文件指针*。stdin——标准输入流。以程序作为主语那么就是程序被输入那么是谁输入到程序里面呢就是从文件或者从键盘上对文程序进行输入比如scanf数据从外部键盘 / 文件进入程序对应scanf/fscanf/fread。stdout——标准输出流。还是以程序作为主语——程序输出那么就是对文件或者对屏幕的写入数据从程序输出到外部屏幕 / 文件对应printf/fprintf/fwrite/fputc。stderr——标准错误流。输入流和输出流是从程序的角度来看的每个被使用的文件都在内存中开辟了一个相应的文件信息区用来存放文件的相关信息比如文件的名字状态、以及文件当前的位置。这些信息保存在一个结构体变量中该结构体变量由系统声明取名为FILE。不同编译器的FILE类型包含的内容不完全相同但相似。每当我们打开一个文件系统会自动创建一个FILE结构体变量并填充其中的信息。如果我们想维护创建访问修改传递销毁这个FILE结构的变量一般会用他的指针也就是FILE*类型的指针就是前面说的文件指针。VS2013 中有 的FILE 类型 的申明4.2文件的打开和关闭4.2.1 fopenFILE * fopen ( const char * filename, const char * mode );参数filename是被打开文件的名字。可以是绝对路径的形式也可以是相对路径的形式mode表示对想打开文件的操作方式功能通过fopen函数来打开文件filename确定文件mode确定操作fopen打开文件都会返回一个FILE*的指针变量指向该文件。这时候通过这个指针变量就可以对文件进行操作返回值如果成功打开那么返回的就是一个指针。指针可以访问对应的文件。如果打开失败返回的就是空指针NULL所以一定要对返回值进行判断来验证是否打开成功这是一个打开失败的例子mode的分类文件使用方式含义如果指定文件不存在“r”只读为了输入数据打开一个已经存在的文本文件出错“w”只写为了输出数据打开一个文本文件建立一个新的文件“a”追加向文本文件尾添加数据建立一个新的文件“rb”只读为了输入数据打开一个二进制文件出错“wb”只写为了输出数据打开一个二进制文件建立一个新的文件“ab”追加向一个二进制文件尾添加数据建立一个新的文件“r”读写为了读和写打开一个文本文件出错“w”读写为了读和写建议一个新的文本文件建立一个新的文件“a”读写打开一个文件在文件尾进行读写建立一个新的文件“rb”读写为了读和写打开一个二进制文件出错“wb”读写为了读和写新建一个二进制文件建立一个新的文件“ab”读写打开一个二进制文件在文件尾进行读和写建立一个新的文件凡是有r的都是和读有关如果找不到读不了那么就出错凡是有w的都是和写有关如果文件存在打开时就会直接把文件里的原有内容清空截断为 0 字节然后再进行写操作。如果没有就自己创建一个再写是有a的都是在后面添加如果没有文件的话就自己创建如果有文件 就直接在后面添加数据凡是在r或w或a后面添加了一个b就代表操作的文件是二进制文件凡是在 后面添加了一个就代表现在既可以有读的操作又可以有写的操作不过 指定文件不存在的时候 结果还是不一样的绝对路径与相对路径相对路径直接在我现在的这个路径里面创建一个这时候我们移动一下路径把这个文件移动到上一级路径中如果这时候再想要访问我们就需要用 “.” “…” “/” 这三个操作符来进行访问“.”代表是此路径“…” 代表是上一个路径“/” 是访问的时候进行上下路径切换的必要符号./../data.txt意思就是这个路径的上一个路径中的data.txt这个文件没有报错说明打开成功了同理我再次把data.txt移动到上一级文件修改我们的打开方式之后,也可成功打开再次移动,移动到上一级文件的上一级文件名称是code的下一级文件Project1的下一级文件.vs中也是成功打开没有报错绝对路径如果我们把这个文件放到桌面,尝试通过绝对路径打开通过右键再点击属性能够看到绝对路径**考虑一下斜杠写哪种格式 **有三种写法\是电脑路径下面默认显示的\\是为了防止上面这种路径被识别成转义字符\n换行\t制表符\代表一个双引号\代表一个单引号,\\代表一个反斜杠的一种写法/是一种不会出错的写法所以我们一般也这么写如果我们按照文件顺序来, 它使用的是转义字符也会使用的斜杠, 可能会和转义字符重合所以我们一般写成下面的这种形式当然按照我们之前用的那种斜杠也可以4.2.2 fclose关闭参数 stream 关联的⽂件并取消其关联关系——相当于给指针free了一下不过这里是关闭文件流解除关联的意思与该流关联的所有内部缓冲区均会解除关联并刷新未写⼊的 输出缓冲区的内容 将被写⼊放到缓冲区的直接给放到文件中未读取的 输⼊缓冲区的内容 将被丢弃。从文件中拿出来放到缓冲区准备使用的还没用 也不管了丢了相当于free了一下free完之后就是野指针野指针必须置空4 文件的读写4.1 顺序读写函数名功能适用于fgetc从输入流中读取一个字符所有输入流fputc向输出流中写入一个字符所有输出流fgets从输入流中读取一个字符串所有输入流fputs向输出流中写入一个字符串所有输出流fscanf从输入流中读取带有格式的数据所有输入流fprintf向输出流中写入带有格式的数据所有输出流fread从输入流中读取一块数据文件输入流fwrite向输出流中写入一块数据文件输出流fputcmode应该是和w相关的int fputc ( int character, FILE * stream );把单个字符写入到stream指向的输出流中用于向文件中写入字符向标准输入流屏幕中写入字符没有报错就说明成功了打开文件来看一眼接下来我们切换到标准输出流其实就是屏幕上面的操作其实通过putchar也能实现循环写入a到z我这少写了一个fgetcmode应该是和r相关的int fgetc ( FILE * stream );功能从参数 stream 指向的流中读取⼀个字符。函数返回的是⽂件指⽰器当前指向的字符读取这个字符之后⽂件指⽰器⾃动前进到下⼀个字符。**人话版功能**如果是第一次用它就读取对应文件的第一个字符。然后呢它会移动光标移动到第一个字符后面那么 你如果接下来再次使用读取的就是第二个字符。以此类推参数stream : FILE*类型的⽂件指针可以是 stdin 也可以是其他输⼊流的指针。如果是 stdin 就从标准输⼊流读取数据。如果是⽂件流指针就从⽂件读取数据。**人话版参数 **文件或者是键盘——这是输入流也就是要从别的地方把内容输入到程序中返回值成功时返回读取的字符以 int 形式。若调⽤时流已处于⽂件末尾函数返回 EOF 并设置流的⽂件结束指⽰器 feof 。若发⽣读取错误函数返回 EOF 并设置流的错误指⽰器 ferror 。人话版返回值成功就返回它读取到的字符的ASCII码值取失败返回EOF这时候你可以用两个函数来判断是哪一种读取失败feof调用时流已经处于文件末尾ferror读取错误用fgetc读取上面写入的文件中的第一个a并且用三种方式打印出来三种方式分别是fputcPut charprintf错误示例错误原因在我们使用fopen的时候打开方式是w。 如果本来没有这个文件它会创建一份新的文件但如果本来有这个文件——它会把文件的所有内容都清空这时候我们在想通过f get c来获取就不行就会出错正确示例(我这还有个错误我最后忘了关闭文件 并且把文件指针置空了)使用for循环循环使用fgetc读取并且使用fputc输出到屏幕上使用fgetc从键盘上读取这里有个问题大家发现没有因为我这个for循环应该是循环6次才对但是我却只输入了3次然后他给我打印了3次这是为什么呢这是因为我输入内容之后要回车一下回车就是一个回车符\n。这两个字符会直接消耗掉两次循环。所以我虽然输入的是3个字符但我产生的却是6个字符因为还有3个\n换行符。那如何才能正确打印出6个字符呢答案是一次性输入6个字符之后再按回车feof和ferrorint feof ( FILE * stream );int ferror ( FILE * stream );在读取文件时可能会发生两种错误导致读取文件结束第一种情况是遇到了文件末尾。读取函数会在对应的流上设置文件结束的指示符这个指示符可以通过feof函数检测。检测到了返回非零没检测到返回零。第二个错误是读或写发生错误导致文件结束。读或写的函数 会在流上设置错误指示符。ferror函数可以检测到错误指示符。检测到了返回非0值没检测到返回零。简单来说这两个函数就是来判断是哪一种情况导致了读文件停止前面我们知道fgetc取失败返回EOF所以我们可以通过返回值是否是EOF来判断文件是否读取过程中停止了。然后这时候再通过前面讲的这两个函数来判断是哪一种情况导致文件读取停止feof本来我只有25个字母但是我却打印了28次导致读取到文件末尾出错返回EOFferror:fputsmode应该是和w相关的前面我们说过fputc它是把一个字符放到文件中或屏幕上是标准输入流。这里也是同理只不过不是一个字符了而是一个字符串int fputs ( const char * str, FILE * stream );功能把字符指针指向的字符串写入stream指定的流中 输入流可以是标准输出流也就是屏幕就是打印到屏幕上。或者是把程序中的内容给输出到文件中。不放\0参数首先是一个字符指针const char * str。也就是一个字符串/字符数组 的数组名然后是文件指针stream可以是向一个文件或者是指向屏幕 标准输出流返回值成功 返回非负数失败返回EOF因为我是从程序向文件放东西所以不需要考虑读到文件末尾使用feof判断错误原因因为根本不是读而是在写所以只有一个可能错误——只需要用ferror检查错误原因由图可知如果想换行的话也要自己添加换行符\n这个添加字符串也是识别到\0就停fgetsmode应该是和r相关的char * fgets ( char * str, int num, FILE * stream );功能这是往程序中输入东西,是输入流。从stream指定的输入流可以是某个文件指针也可以是键盘也就是标准输入流stdin中读取字符串直到读到换行符\n或文件末尾EOF或达到指定字符数包括结尾的空字符\0然后将读取到的字符串存到str指向的空间中。就是把文件或者键盘上的内容放到字符串里。参数和fputs相同str指向字符数组的指针也就是字符数组的数组名。用来存储读取到的字符串num想要从输入流中读取几个字符stream输入流的文件指针可以是文件流或者标准输入流返回值如果成功读取那返回的还是原来的指针如果读取失败有两种情况 都返回空指针NULL一个是读取到了文件末尾通过feof检测另一个是发生了读取错误通过ferror检测由此可见首先如果我想把文件中的字符串给放到程序中的字符串里面它也只会读到\0为止。如果我想让他读14个字符如果一行只有10个字符它会停下来。读完那一行读到斜杠换行符后就会停下来会把换行符加进去然后再在后面加个\0。然后实际有效的数量是num-1看第二个图片我想让他放9个元素过来但你看看他图片中它只实际上它的确换了9个元素不过第九个元素是\0也就相当于 只放了8个元素fprintfmode应该是和w相关的int fprintf ( FILE * stream, const char * format, ... );功能 fprintf 是将格式化数据写⼊指定⽂件流的函数。它与 printf 类似但可以输出到任意输出流如磁盘⽂件、标准输出、标准错误等⽽不仅限于控制台。简单来说我们之前学的printf是把程序中的内容输出到屏幕上而现在的fprintf可以将程序的内容输出到很多地方比如文件中当然也可以直接输出到屏幕上参数stream表示要写入的文件流可以是文件指针也可以是标准输出流stdout屏幕format就相当于我们之前使用printf时候的双引号里面再加上%s%d那些...可变参数列表提供与格式字符串中说明符对应的数据。和printf相比只是前面多了个stream可以是文件指针也可以是标准输出流stdout返回值成功写入之前使用printf返回成功输出的字符个数包括空格、换行符\n这些。现在使用fprintf也是一样返回写入的总字符数写入失败返回负值。并且设置对应流的错误指示器可以使用ferror来检测因为这是往文件或者往屏幕上写数据不需要考虑读取到文件末尾的问题从程序中输出到文件里的情况从程序中输出到屏幕上的情况fscanf别忘了mode应该是和r相关的int fscanf ( FILE * stream, const char * format, ... );功能fscanf 是从指定⽂件流中读取格式化数据的函数。它类似于 scanf 但可以指定输⼊源如⽂件、标准输⼊等⽽⾮仅限于控制台输⼊。适⽤于从⽂件解析结构化数据如整数、浮点数、字符串等。意思就是之前的scanf是从键盘上读取数据。但现在的fscanf既可以从键盘上读取数据也就是标准输入流也可以从文件中读取数据就是文件流参数stream表示要读取的文件流可以是标准输入流stdin或者文件指针format 格式化字符串定义了如何解析数据我们之前就常用的 如 %d 、 %f 、 %s 等外面也要加上双引号...可变参数列表。提供储存数据的变量的地址我们之前经常写的内容。如果是字符串就写成首元素的地址如果是整形就直接写变量名。返回值读取成功读取了几项就返回几返回值可能小于项数原因有三种可能1.类型不匹配2.读取发生错误3.到了文件末尾失败返回EOF可能原因是读取发生错误或者到达文件末尾fwrite和fread——以二进制形式读写前面讲的都是文本文件的读写函数。现在这两个函数只能对二进制文件进行读写。 我们可以看一下 图 红色框代表他俩只能针对文件输入流和文件输出流。也就是说它俩的对象只能是文件不能是标准输入流或标准输出流也就是不能再通过屏幕打印或者通过屏幕输入size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );使用之前需要确保文件已经以二进制可写方式打开——mode得是rw相关如果我们写入文本数据需要谨慎处理换行符和编码等问题功能以二进制的形式将数据写入文件参数ptr想写入的数据的指针size想写入的数据每个有多大几个字节count想写入几个数据stream指向文件指针指定要写入数据的文件流返回值返回实际写入的数据的数量。如果发生了错误返回值可能会小于count虽然成功运行了但我们还是看不懂这里面写入的是什么因为这是一个二进制文件而不是文本文件size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );功能以二进制的形式将数据写入文件参数和上一个fwrite相同的参数不过这时候的 指针是我们想从文件中读取的内容 放入的地方返回值返回实际读取的数据的数量注意事项头文件stdio.h在使用fopen打开文件的时候必须用二进制可读的方式如果返回值读取数量少于count则可能已经到达文件结尾或者发生了错误——这个时候就需要用feof和ferror来判断文本文件读取一般不用让我们把上一个fwrite存到文件中 的三个量给 放到一个新的结构体s_new中并打印sprintf和sscanf我们知道printf是直接进行标准输出流输出到屏幕上。fprintf也是一种输出不过这种输出更加宽泛可以是文件流也可以是标准输出流——也就是也可以输出到文件中也可以输出到屏幕上那这个sprintf是什么呢——把内容给输出到一个字符串中。也就是把各种类型的数据比如 一个整数啊或者一个浮点数啊我把它们全部都整合到一个字符串里。我们之前最开始学的scanf是从标准输入流也就是键盘上进行输入操作。然后前面我们学的fscanf是从文件中把数据输入到程序里这里我们要学的sscanf就是把输入到程序中的输入源 变成一个字符串。 假如我想往一个整型再往一个浮点型里输入数据那么我可以直接给输入源是一个字符串这个字符串虽然本质是字符串但是里面却像是由一个整数和一个浮点数组成的那这个函数就可以帮助我们进行转化输入int sprintf ( char * str, const char * format, ... );将各种东西变成一个字符串放到str指向的地方int sscanf ( const char * str, const char * format, ...);将一个源字符串转化成各种东西三组函数的对比函数名功能描述scanf针对标准输入流stdin的格式化输入函数printf针对标准输出流stdout的格式化输出函数fscanf针对所有输入流可以是文件流也可以是stdin的格式化输入函数fprintf针对所有输出流可以是文件流也可以是stdout的格式化输出函数sprintf将格式化的数据转换成字符串sscanf从字符串中提取格式化的数据4.2随机读写fseekint fseek ( FILE * stream, long int offset, int origin );功能根据文件指针的位置和偏移量来定位文件指针——改变光标的位置参数stream文件指针offset相较于origin的偏移量可以是正负或零。正数代表向文件末尾移动负数代表向文件开头移动0代表不移动origin偏移的起始点基准位置有三种写法SEEK_SET 开始的位置SEEK_CUR 文件指针当前的位置SEEK_END 文件末尾的位置返回值成功返回0失败返回一个负数通常为-1ftelllong int ftell ( FILE * stream );功能返回文件指针相对于起始位置的偏移量参数stream指向一个已打开的文件指针返回值成功返回相对于起始位置的偏移量类型是long int失败如果发生错误文件流无效或者不支持偏移则返回 -1Llong int类型的-1rewindvoid rewind ( FILE * stream );功能让文件指针的位置回到文件的起始位置参数stream指向一个已打开文件的文件指针等价于fseek(pf, 0, SEEK_SET);5.内存缓冲区ANSI C 标准采⽤“缓冲⽂件系统” 处理数据⽂件的所谓缓冲⽂件系统是指系统⾃动地在内存中为程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据则从磁盘⽂件中读取数据输⼊到内存缓冲区充满缓冲区然后再从缓冲区逐个地将数据送到程序数据区程序变量等。缓冲区的⼤⼩根据C编译系统决定的。从内存向磁盘输入数据或者从磁盘向计算机读入数据并不是一下就完成的。而是先将数据输入到内存缓冲区缓冲区充满后再逐个将数据送到程序数据。不同编译系统的缓冲区大小也不同在前面我们对文件进行读写的时候假设我们是要往文件里写东西在程序没有调用fclose的时候并不会真正把内容写进去。那这时候那些内容存到哪里了呢它们在文件缓冲区中。使用fclose后会刷新这时候缓冲区未写入的数据才会写出。fclose在关闭文件前会自动调用fflush把缓冲区里所有没写入的数据强制刷新到磁盘再释放资源fflushint fflush ( FILE * stream );功能强制刷新参数stream指定的流的缓冲区确保数据写入底层设备对输入流将缓冲区未写入的数据立即写入文件。对输出流不确定非C语言标准行为。参数为NULL时刷新所有打开的输出流参数stream指向文件流的指针如stdout文件指针返回值成功返回0失败返回eof注意事项仅对输出流 或 更新流有明确的刷新行为对输入流的刷新行为是非C语言标准定义的程序正常终止或者调用fclose的时候也会调用fflash, 但程序崩溃时缓冲区可能丢失当你在运行下面的代码的时候你打开记事本用记事本访问对应的TXT文件也是可以看到文件中的变化这能够说明缓冲区的存在和它的运行规律#includestdio.h#includewindows.h//VS2022 WIN11环境测试intmain(){FILE*pffopen(test.txt,w);fputs(abcdef,pf);//先将代码放在输出缓冲区printf(睡眠10秒-已经写数据了打开test.txt⽂件发现⽂件没有内容\n);Sleep(10000);printf(刷新缓冲区\n);fflush(pf);//刷新缓冲区时才将输出缓冲区的数据写到⽂件磁盘//注fflush 在⾼版本的VS上不能使⽤了printf(再睡眠10秒-此时再次打开test.txt⽂件⽂件有内容了\n);Sleep(10000);fclose(pf);//注fclose在关闭⽂件的时候也会刷新缓冲区pfNULL;return0;}6.更新文件在讲mode的分类的时候这6种情况显得尤为特殊它们既可以读又可以写。一般在更新文件的时候用行为rwa解释可读 / 可写可读 / 可写可读 / 可写文件不存在时打开失败自动创建新文件自动创建新文件文件存在时保留内容清空内容保留内容初始文件指针位置文件开头文件开头文件末尾写入是否覆盖原有数据是可定位覆盖是内容已清空从头写入否默认是在文件末尾写数据典型用途修改文件部分内容创建新文件或完全重写旧文件在文件末尾追加数据比如记录日志关键要点如果既想读又想写那么打开方式mode 必须使用前面说的带加号的六种类型首先上一小节说了文件缓冲区的概念。在你 往文件里写东西时不是你写了一下fputs它就直接放进去了。这时候你必须使⽤ fflush()刷新一下缓冲区fputs的功能才能实现。然后这时候你 不知道文件指针现在指向什么地方这时候你也得用fseek() rewind()重新定位一下文件指示器的位置在读完文件后继续写文件之前也得用fseek() rewind()重新定位一下文件指示器的位置既然看到这里了不妨点赞收藏感谢大家若有问题请指正。