个人主页 流年如夢专栏 《C语言》文章目录一.了解文件1.1为什么需要使用文件1.2什么是文件二.二进制文件和文本文件2.1文本文件2.2二进制文件三.文件的打开fpoen和关闭fclose3.1流和标准流3.2文件指针3.3fopen -- 打开文件3.4fclose -- 关闭文件3.5举例四.文件的顺序读写[cplusplus链接](https://legacy.cplusplus.com/)表格4.1fputc与fgetc4.1.1函数原型4.1.2举例4.2fputs与fgets4.2.1函数原型4.2.2举例4.3fprintf与fscanf4.3.1函数原型4.3.2举例4.4fwrite与fread4.41函数原型4.4.2举例4.5三组函数对比五.文件的随机读写5.1fseek -- 定位文件指针5.2ftell -- 获取当前偏移5.3rewind -- 回到文件开头六.文件读取结束的判定feof与ferror6.1feof6.2ferror七.文件缓冲区八.更新文件r、w、a总结⚠️易错点Ladies and gentlemen本篇文章讲的是文件操作下面将带领大家学习文件打开关闭fopen、fclose、顺序读写、随机读写、结束判定、文件缓冲区、更新文件等全程高能不容错过前言程序运行时的数据都存放在内存中程序退出后数据就会丢失。如果想让数据持久化保存就必须用到文件操作。C语言提供了完整的文件读写接口支持文本和二进制两种存储格式能实现数据的写入、读取、修改、追加等功能。本篇文章带你从零掌握文件操作写出稳定、安全、规范的文件处理代码。一.了解文件1.1为什么需要使用文件因为程序退出后内存数据会被回收数据无法保存但使用文件可以把数据存放在硬盘中实现数据持久化在下次运行程序时可以从文件中读取历史数据。1.2什么是文件磁盘上的文件就是文件例如我们电脑都有的C盘和D盘当然在程序设计中分为两类程序文件和数据文件程序文件源文件.c目标文件.obj可执行程序.exe数据文件本篇重点程序运行时用于读写数据的文件文件名文件名 文件路径 文件名主干 后缀例如c:\code\test.txt二.二进制文件和文本文件2.1文本文件以ASCII字符形式存储可以直接看懂的2.2二进制文件以内存二进制形式存储节省空间、读写快举个例子#includestdio.hintmain(){inta10000;FILE*pffopen(test.txt,wb);fwrite(a,4,1,pf);fclose(pf);pfNULL;return0;}分析wb是以二进制只写方式打开fwrite是按二进制写入int只占4字节运行结果在这里程序没有报错说明运行成功这时双击左上角打开文件test.txt或ctrlc我们可以看到10000以二进制方式写入文件如下所示三.文件的打开fpoen和关闭fclose3.1流和标准流流stream数据传输的抽象可理解为 “数据的河流”三个默认标准流stdin-- 标准输入用键盘stdout-- 标准输出在屏幕上stderr-- 标准错误3.2文件指针每个打开的文件系统都会创建一个FILE结构体信息区我们用FILE*指针来操作文件3.3fopen -- 打开文件函数原型FILE*fopen(constchar*filename,constchar*mode);其中打开失败返回NULL必须判断mode是打开方式例如r、w、a、rb、wb、ab、r、w、a…3.4fclose – 关闭文件函数原型intfclose(FILE*stream);使用fclose关闭文件并刷新缓冲区关闭后必须把指针置 NULL3.5举例#includestdio.hintmain(){FILE*fpfopen(test.txt,r);//这里先打开文件if(fpNULL){perror(fopen);return1;}// 读写操作...fclose(fp);//最后关闭文件fpNULL;return0;}分析先打开判断、用完关闭、最后指针置空perror是用来直接打印错误原因方便调试四.文件的顺序读写cplusplus链接表格函数功能适用fputc写一个字符所有输出流fgetc读一个字符所有输入流fputs写一行字符串所有输出流fgets读一行字符串所有输入流fprintf格式化写入所有输出流fscanf格式化读取所有输入流fwrite二进制块写入文件流fread二进制块读取文件流4.1fputc与fgetc4.1.1函数原型功能向指定流中写入一个字符写完后文件指针自动后移参数character是要写入的字符stream是目标文件流返回值成功返回写入的字符失败返回EOF功能从指定流中读取一个字符读完后文件指针自动后移参数stream是要读取的文件流返回值成功返回读到的字符读到末尾或出错返回EOF4.1.2举例//写入fputc(a,fp);//读取intchfgetc(fp);4.2fputs与fgets4.2.1函数原型功能向文件中写入一个字符串不写入末尾\0参数str是要写入的字符串stream是目标文件流返回值成功返回非负数失败返回EOF功能从文件中读取一行或指定长度字符串参数str是存放读取内容num是最多读num-1个字符stream是文件流返回值成功返回str失败或到末尾返回NULL4.2.2举例fputs(hello world,fp);charbuf[100]{0};fgets(buf,100,fp);4.3fprintf与fscanf4.3.1函数原型功能格式化写入文件用法和printf几乎一样参数stream是目标流format是格式化字符串后续为输出参数返回值成功返回写入字符数失败返回负数功能格式化读取文件内容用法和scanf类似参数stream是输入流format是格式串后续为地址参数返回值成功返回读取参数个数失败或到末尾返回EOF4.3.2举例structStu{charname[20];intage;};//写入fprintf(fp,%s %d,s.name,s.age);//读取fscanf(fp,%s %d,s.name,s.age);//数组name本身就是指针不需要 4.4fwrite与fread4.41函数原型功能以二进制形式整块写入文件参数ptr是数据地址size是一个元素大小count是元素个数stream是文件流返回值成功写入的元素个数功能以二进制形式从文件整块读取数据参数ptr是接收数据的缓冲区size是一个元素大小count是要读个数stream是文件流返回值实际读到的元素个数4.4.2举例//写入fwrite(s,sizeof(structStu),1,fp);//读取fread(s,sizeof(structStu),1,fp);4.5三组函数对比函数功能scanf从标准输入读fscanf从任意流读sscanf从字符串读printf打印到标准输出fprintf打印到任意流sprintf打印到字符串五.文件的随机读写5.1fseek -- 定位文件指针函数原型SEEK_SET -- 文件开头SEEK_CUR -- 当前位置SEEK_END -- 文件末尾例如fseek(fp,offset,origin);5.2ftell -- 获取当前偏移函数原型功能返回当前文件指针相对于开头的偏移量例如longposftell(fp);5.3rewind -- 回到文件开头函数原型功能把文件指针重置到文件开头例如rewind(fp);六.文件读取结束的判定feof与ferror6.1feof判断是否是正常读到文件末尾if(feof(fp))printf(读到文件末尾\n);6.2ferror判断是否是发生读取错误if(ferror(fp))printf(读取出错\n);注意feof不是用来判断是否结束而是结束后判断是 “读到尾” 还是 “出错”七.文件缓冲区系统会为每个文件自动开辟缓冲区数据先写缓冲区满了或刷新才写入磁盘fflush(fp)会强制刷新缓冲区fputs(abc,fp);fflush(fp);//立即写入磁盘八.更新文件r、w、a模式文件不存在原有内容指针位置r打开失败保留开头w创建新文件清空开头a创建新文件保留末尾规则写完读必须fflush或fseek读完写必须fseek或rewind总结文件用于数据持久化分为文本文件和二进制文件操作流程为fopen-- 读写 --fclose-- 置空NULL打开文件必须判断是否为NULL顺序读写有fgetc、fputc、fgets、fputs、fprintf、fscanf二进制读写有fread与fwrite随机读写fseek、ftell、rewind结束判定时要用feof和ferror区分结束原因缓冲区fflush强制刷新fclose自动刷新更新模式读写切换必须刷新或重定位⚠️易错点不判断fopen返回值直接使用空指针忘记fclose导致数据丢失、文件占用fclose后不置空形成野指针混淆文本方式与二进制方式fgets读取时包含\n处理不当出错读写切换不刷新、不定位导致读写异常用feof提前判断循环结束逻辑错误