【C语言】文件操作揭秘:C语言中文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析【图文详解】
欢迎来CILMY23的博客喔,本篇为【C语言】文件操作揭秘:C语言中文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析【图文详解】,感谢观看,支持的可以给个一键三连,点赞关注+收藏。
前言
欢迎来到本篇博客,上一篇我们详细介绍C语言中的文件操作。
在计算机领域,文件是一种常见的存储和处理信息的方式。通过文件,我们可以将数据和程序永久保存在硬盘中,并随时读取和修改。本篇博客将深入探讨文件操作、文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析。
上一篇博客链接:
【C语言】文件操作篇-----程序文件和数据文件,文件的打开和关闭,二进制文件和文本文件,fopen,fclose【图文详解】-CSDN博客
文章目录
一、文件的顺序读写
1.1 文件顺序读写的函数介绍:
1.2 fgetc和fputc的使用
1.3 fgets和fputs的使用
1.4 fprintf和printf的使用
1.5 fscanf和scanf的使用
1.6 sscanf和sprintf的介绍和使用
1.7 fwrite和fread的使用
1.8 总结
二、文件的随机读写
2.1 fseek函数
2.2 ftell函数
三、文件读取结束的判定
四、文件缓冲区
一、文件的顺序读写

文件顺序读写是指按照数据在文件中的顺序依次读取或写入数据的操作方式。在文件顺序读写中,数据按照其存储在文件中的顺序被逐个读取或写入。
对于顺序读取,程序会依次读取文件中的数据,从文件的开头一直读取到末尾,直到到达文件结束的位置或者读取到所需的数据为止。每次读取数据后,读取指针会自动向后移动到下一个数据的位置。
对于顺序写入,程序会依次将数据写入文件,从文件的结尾开始写入,每写入一个数据后,写入指针会自动移动到下一个位置,以便写入下一个数据。这样,数据会按照写入的顺序依次添加到文件中。
1.1 文件顺序读写的函数介绍:

上面说的使用于所有输入流⼀般指使用于标准输入流和其他输入流(如文件输入流);所有输出流⼀般指使用于标准输出流和其他输出流(如文件输出流)。
fgetc和fputc: 这两个函数用于逐个字符地读取和写入文件。(一次读取(写入)一个)它们的原型如下:
int fgetc(FILE *stream); int fputc(int character, FILE *stream);
fgets:从指定文件中读取一行数据(包括换行符),并将其存储到指定的字符数组中。原型如下:
char *fgets(char *str, int n, FILE *stream);
fputs:将指定的字符串写入到指定文件中。(一次写一行数据)原型如下:
int fputs(const char *str, FILE *stream);
fscanf: 该函数用于从文件中按照指定的格式读取数据。它的原型如下:
int fscanf(FILE *stream, const char *format, ...);
fprintf: 该函数用于向文件中按照指定的格式写入数据。它的原型如下:
int fprintf(FILE *stream, const char *format, ...);
fread函数:
- 函数原型:
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);- 功能:从指定文件中读取二进制数据,并将其存储到指定的内存位置。
- 参数:
ptr:指向存储读取的数据的内存位置的指针。size:每个数据项的字节数。count:要读取的数据项的个数。stream:指向已打开文件的指针,表示从该文件中读取数据。- 返回值:返回实际成功读取的数据项数目,如果返回值少于
count,则可能表示已到达文件末尾或发生了错误。
fwrite函数:
- 函数原型:
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
- 功能:将二进制数据写入指定文件中。
- 参数:
ptr:指向要写入的数据的内存位置的指针。size:每个数据项的字节数。count:要写入的数据项的个数。stream:指向已打开文件的指针,表示将数据写入到该文件中。- 返回值:返回实际成功写入的数据项数目,如果返回值少于
count,则可能表示发生了错误。
1.2 fgetc和fputc的使用
我们现在在当前路径下:C:\Users\云山若汐\source\repos\test2\test2
放入两个文件,
write可以不放,然后我们在text中输入abcd,我们现在将要拷贝当中的字符到write中,所以写下以下代码:
#include<stdio.h>int main()
{char ch;FILE* pfread = fopen("text.txt", "r");if (pfread == NULL){perror("fopen - 1");return 1;}FILE* pfwrite = fopen("write.txt", "w");if (pfwrite == NULL){perror("fopen - 2");return 1;}while ((ch = fgetc(pfread)) != EOF){fputc(ch, pfwrite);}fclose(pfread);pfread = NULL;fclose(pfwrite);pfwrite = NULL;
}
效果如下:

1.3 fgets和fputs的使用
假设此时text中有两行,它们分别是:

int main()
{char arr[20];FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("fopen");return 1;}fgets(arr, 20, pf);printf("%s", arr);fclose(pf);pf = NULL;return 0;
}
我们使用fgets从文件中获取信息,注意fgets只会从指定文件中读取一行数据(包括换行符)也就是换行符是固定的,我们读取20只会读取前十九个字符因为最后一个字符要存放换行符。
1.4 fprintf和printf的使用
假设我们定义了一个结构体如下所示,那我们可以使用printf将其打印到屏幕上,也可以使用fprintf将其打印至屏幕上,或者将其写入文件中
struct S
{int n;float f;char arr[100];
};int main()
{struct S s = { 100,3.14f,"zhangsan" };FILE* pf = fopen("text.txt", "w");if (pf == NULL){perror("fopen");return 1;}//输出到屏幕上printf("%d %f %s\n", s.n, s.f, s.arr);fprintf(stdout, "%d %f %s", s.n, s.f, s.arr);//使用fprintf输出到文件中fprintf(pf, "%d %f %s\n", s.n, s.f, s.arr);fclose(pf);pf = NULL;return 0;
}
效果如下:


1.5 fscanf和scanf的使用
struct S
{int n;float f;char arr[100];
};int main()
{struct S s = {0};FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("fopen");return 1;}fscanf(pf,"%d %f %s",&(s.n), &(s.f), &(s.arr));printf("%d %f %s", s.n, s.f, s.arr);fclose(pf);pf = NULL;return 0;
}
我们用"fopen"打开一个名为"text.txt"的文件来读取数据。如果打开成功,你使用"fscanf"函数从文件中读取整数、浮点数和字符串,存储到结构体"s"的相应成员中。注意,在"%s"格式符后,使用"s.arr"而不是"&"操作符(因为数组名本身就是数组的首地址)
1.6 sscanf和sprintf的介绍和使用
在本文中,我们将介绍C++中两个常用的输入输出解析函数:sscanf和sprintf。这两个函数提供了灵活的方式来处理字符串和变量之间的格式化输入输出操作。
- sscanf函数:
- sscanf函数用于将字符串按照指定的格式解析,并将解析后的值存储到对应的变量中。
- 语法:int sscanf(const char* str, const char* format, ...)
- str为输入的字符串,format为格式化字符串,...为对应的变量列表。
#include <stdio.h>int main() {const char* str = "23.5 10";float f;int i;sscanf(str, "%f %d", &f, &i);printf("解析出的浮点数为:%.2f\n", f);printf("解析出的整数为:%d\n", i);return 0;
}
- sprintf函数:
- sprintf函数用于将格式化的数据输出到字符串中。
- 语法:int sprintf(char* str, const char* format, ...)
- str为输出的字符串,format为格式化字符串,...为对应的变量列表。
#include <stdio.h>int main() {char str[100];int i = 42;float f = 3.14;sprintf(str, "整数:%d,浮点数:%.2f", i, f);printf("格式化后的字符串:%s\n", str);return 0;
}
sscanf和sprintf函数是C语言中常用的输入输出解析函数,可以方便地进行字符串的解析和格式化输出
1.7 fwrite和fread的使用
fwrite的使用
#include <stdio.h>int main()
{int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };FILE* pf = fopen("text.txt", "wb");if (pf == NULL){perror("fopen");return 1;}fwrite(arr, sizeof(int), 10, pf); // 写入整个数组fclose(pf);pf = NULL;return 0;
}
我们可以在项目中用二进制形式查看这个txt文件 ,右键该文件,选择打开方式,选择底部的二进制编辑器,

我们可以看到文件中写入了几个数

那如何验证我们是否写入了呢?这时候我们就需要用到fread
int main()
{int arr[10] = {0};FILE* pf = fopen("text.txt", "rb");if (pf == NULL){perror("fopen");return 1;}fread(arr, sizeof(int), 10, pf); int i = 0;for (i = 0; i < 10; i++){printf("%d ", arr[i]);}fclose(pf);pf = NULL;return 0;
}

1.8 总结

二、文件的随机读写
C语言中的随机读写通常指的是以随机的方式访问文件中的数据,而不是按顺序逐个读取或写入。这种随机的读写通常涉及到文件指针的定位,可以根据需要在文件中的不同位置进行读写操作。
C语言提供了两个函数来进行文件的随机读写,它们分别是fseek和ftell
2.1 fseek函数
fseek - C++ Reference (cplusplus.com)
-
fseek 函数:
- 函数原型:
-
int fseek ( FILE * stream, long int offset, int origin ); - 功能:移动文件流中的读写位置,进行随机的文件定位。
- 参数:
- stream:指向文件的指针。
- offset:偏移量,用于指定文件指针要移动的位置。
- origin:指定起始位置,可以取三个值:
- SEEK_SET :文件的开始位置
- SEEK_CUR:文件指针的当前位置
- SEEK_END:文件的末尾位置
- 返回值:如果成功,返回0;否则,返回非0值(通常是-1)。
fseek的使用,fseek函数主要有三种origin的起始值
至于偏移量就是距离我的origin有多远了,从1字节开始算
例如:
假设我的text里存了CILMY23
#include <stdio.h>int main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("fopen");return 1;}fseek(pf, 0, SEEK_SET);//Cchar ch = fgetc(pf);printf("%c\n", ch);fseek(pf, -1, SEEK_END);//3ch = fgetc(pf);printf("%c\n", ch);fseek(pf, -5, SEEK_CUR);//Lch = fgetc(pf);printf("%c\n", ch);fclose(pf);pf = NULL;return 0;
}
2.2 ftell函数
ftell - C++ Reference (cplusplus.com)
ftell函数:
- 原型:
long int ftell ( FILE * stream );- 功能:获取当前文件位置指针的偏移字节数。
- 参数:
- stream:指向文件的指针。
- 返回值:返回当前文件位置指针的偏移字节数。
例如:
#include <stdio.h>int main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("fopen");return 1;}fseek(pf, -1, SEEK_END);//3char ch = fgetc(pf);printf("%c\n", ch);int ret = ftell(pf);printf("%d", ret);fclose(pf);pf = NULL;return 0;
}
三、文件读取结束的判定
文件读取结束可以通过feof函数进行判定。feof函数用于检测文件流上的结束标志。当文件末尾已经读取,feof函数返回非零值;否则返回0。
文件读取结束的原因可能有:
1.文件遇到末尾
2.文件发生错误
#include<stdio.h>int main()
{FILE* pf = fopen("text.txt", "r");if (pf == NULL){perror("fopen");return 1;}int ch;while ((ch = fgetc(pf)) != EOF){// 处理读取的字符if (feof(pf)){printf("文件读取结束\n");}else{printf("文件读取出错\n");}}fclose(pf);pf = NULL;return 0;
}
所以在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束。feof 的作用是:当文件读取结束的时候,判断是读取结束的原因是否是:遇到文件末尾结束
1. 文本文件读取是否结束,判断返回值是否为EOF(fgetc ),或者NULL(fgets )
例如:
• fgetc 判断是否为 EOF .
• fgets 判断返回值是否为NULL .
2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。 例如:
• fread判断返回值是否小于实际要读的个数。
四、文件缓冲区
ANSIC标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为 程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓 冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。

因为有缓冲区的存在,C语言在操作文件的时候,需要做刷新缓冲区或者在文件操作结束的时候关闭文件。如果不做,可能导致读写文件的问题。
通过本篇博客,相信你了解了C语言中文件操作的核心内容。文件的顺序读写、随机读写、文件读取结束的判定以及文件缓冲区等知识点,感谢你的阅读!如果你对文件操作还有任何疑问或需要进一步的帮助,请随时留言,如果你觉得还不错的话,可以给个一键三连,点赞关注加收藏,本篇博客就到此结束了。
相关文章:
【C语言】文件操作揭秘:C语言中文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析【图文详解】
欢迎来CILMY23的博客喔,本篇为【C语言】文件操作揭秘:C语言中文件的顺序读写、随机读写、判断文件结束和文件缓冲区详细解析【图文详解】,感谢观看,支持的可以给个一键三连,点赞关注收藏。 前言 欢迎来到本篇博客&…...
JAVA八股文面经问题整理第6弹
文章目录 目录 文章目录 提问问题 问题1 问题2 问题3 问题4 问题5 问题6 问题7 问题8 问题9 问题10 问题11 问题12 写在最后 提问问题 介绍一下Linux常⽤命令,例如:Vim快捷键,常⽤查看Log的命令,路径相关&#x…...
pytest相关面试题
pytest是什么?它有什么优点? pytest是一个非常流行的Python测试框架,它具有简洁、易用、高校等优点。他可以帮助测试人员方便地编写和运行测试用例,并且提供了丰富的插件和扩展,支持各种测试需求介绍下pytest常用的库 …...
Keras库搭建神经网络
Keras并非简单的神经网络库,而是一个基于Theano的强大的深度学习库,利用它不仅仅可以搭建普通的神经网络,还可以搭建各种深度学习模型,如自编码器、循环神经网络、递归神经网络、卷积神经网络等。 安装代码: pip ins…...
适配器模式与桥接模式-灵活应对变化的两种设计策略大比拼
🌈 个人主页:danci_ 🔥 系列专栏:《设计模式》 💪🏻 制定明确可量化的目标,坚持默默的做事。 🚀 转载自:设计模式深度解析:适配器模式与桥接模式-灵活应对变…...
Elasticsearch8搭建及Springboot中集成使用
1.搭建 1.1.下载地址 Elasticsearch:https://www.elastic.co/cn/downloads/elasticsearch Kibana:https://www.elastic.co/cn/downloads/kibana 1.2.具体过程 下载安装包:访问上述链接,下载适合你操作系统的Elasticsearch和Ki…...
asp.net在线租车平台
说明文档 运行前附加数据库.mdf(或sql生成数据库) 主要技术: 基于asp.net架构和sql server数据库 功能模块: asp.net在线租车平台 用户功能有首页 行业新闻用户注册车辆查询租车介绍访问后台 后台管理员可以进行用户管理 管…...
Beamer模板——基于LaTeX制作学术PPT
Beamer模板——基于LaTeX制作学术PPT 介绍Beamer的基本使用安装和编译用于学术汇报的模板项目代码模板效果图 Beamer的高级特性动态效果分栏布局定理环境 介绍 在学术领域,演示文稿是展示和讨论研究成果的重要方式。传统的PowerPoint虽然方便,但在处理复…...
性能测试-Jmeter中IF控制器使用
一、Jmeter控制器 分为两种类型: 控制测试计划执行过程中节点的逻辑执行顺序,如:循环控制器,if控制器等对测试计划中的脚本进行分组,方便Jmeter统计执行结果以及进行脚本的运行时控制等,如:吞…...
华为综合案例-普通WLAN全覆盖配置(2)
组网图 结果验证 在AC_1和AC_2上执行display ap all命令,检查当前AP的状态,显示以下信息表示AP上线成功。[AC_1] display ap all Total AP information: nor : normal [1] ExtraInfo : Extra information P : insufficient power supply ---…...
这里是一本关于 DevOps 企业级 CI/CD 实战的书籍...
文章目录 📋 前言🎯 什么是 DevOps🎯 什么是 CI/CD🎯什么是 Jenkins🧩 Jenkins 简单案例 🎯 DevOps 企业级实战书籍推荐🔥 参与方式 📋 前言 企业级 CI/CD 实战是一个涉及到软件开发…...
机器学习 - save和load训练好的模型
如果已经训练好了一个模型,你就可以save和load这模型。 For saving and loading models in PyTorch, there are three main methods you should be aware of. PyTorch methodWhat does it do?torch.saveSaves a serialized object to disk using Python’s pickl…...
【动态规划】【同余前缀和】【多重背包】[推荐]2902. 和带限制的子多重集合的数目
本文涉及知识点 动态规划汇总 C算法:前缀和、前缀乘积、前缀异或的原理、源码及测试用例 包括课程视频 C算法:滑动窗口总结 多重背包 LeetCode2902. 和带限制的子多重集合的数目 给你一个下标从 0 开始的非负整数数组 nums 和两个整数 l 和 r 。 请你…...
nginx介绍及搭建
架构模型 Nginx是由一个master管理进程、多个worker进程组成的多进程模型。master负责管理worker进程,worker进程负责处理网络事件,整个框架被设计为一种依赖事件驱动、异步、非阻塞的模式。 优势: 1、充分利用多核,增强并发处理…...
树莓派夜视摄像头拍摄红外LED灯
NoIR相机是一种特殊类型的红外摄像头,其名称来源于"No Infrared"的缩写。与普通的彩色摄像头不同,NoIR相机具备红外摄影和低光条件下摄影的能力。 一般摄像头能够感知可见光,并用于普通摄影和视频拍摄。而NoIR相机则在设计上去除了…...
Oracle19C静默安装教程
文章目录 一、安装前的准备1、安装Linux操作系统2、配置网络源或者本地源3、hosts文件配置 二、准备安装环境1、安装依赖包2、创建oracle用户组3、配置系统内核参数4、关闭selinux5、配置oracle用户环境6、修改用户的Shell限制 三、静默安装Oracle数据库1、创建oracle安装目录2…...
【机器学习】基于粒子群算法优化的BP神经网络分类预测(PSO-BP)
目录 1.原理与思路2.设计与实现3.结果预测4.代码获取 1.原理与思路 【智能算法应用】智能算法优化BP神经网络思路【智能算法】粒子群算法(PSO)原理及实现 2.设计与实现 数据集: 多输入多输出:样本特征24,标签类别4…...
Sora后时代文生视频的探索
一、写在前面 按常理,这里应该长篇大论地介绍一下Sora发布对各行业各方面产生的影响。不过,这类文章已经很多了,我们今天主要聊聊那些已经成熟的解决方案、那些已经可以“信手拈来”的成果,并以此为基础,看看Sora发布…...
指南:在各主流操作系统上安装与配置Apache Tomcat
指南:在各主流操作系统上安装与配置Apache Tomcat Apache Tomcat作为一款广受欢迎的开源Java Servlet容器,为用户提供了一个纯Java环境下的Web服务器和Servlet容器。本文将详细介绍如何在不同的操作系统上安装Apache Tomcat,并进行基本的配置…...
物联网的介绍
物联网(Internet of Things,简称IoT)是指通过互联网将物理设备、传感器、通信设备和软件系统相互连接,形成一个网络化的系统。它可以实现设备之间的数据交换、信息共享和远程控制,使得物理世界与数字世界紧密结合。 物…...
基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
【AI学习】三、AI算法中的向量
在人工智能(AI)算法中,向量(Vector)是一种将现实世界中的数据(如图像、文本、音频等)转化为计算机可处理的数值型特征表示的工具。它是连接人类认知(如语义、视觉特征)与…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
