【C语言】文件操作(2)

news2025/4/25 17:13:07

一、文件的随机读写

在前面我们学习了文件的顺序读写的函数,那么当我们要读取某个指定位置的内容的时候,是否只能顺序的读取到这个内容?还有在对文件进行输入的时候,需要对指定的位置进行写入,那么此时应该怎么办呢?

我们也可以使用函数来更改读写的位置的,从而实现随机读写。

1、fseek函数

 fseek函数是用来定义文件内容的光标,光标是默认在文件的开头的,我们前面使用的顺序读写的函数,其是使用一次后,光标是会向后移动一个位置的。·而fseek函数可以通过偏移量来定位光标,然后再从这个位置进行读写。

原型:

int freek(FILE*stream,long int offset,int origin );

如果函数定位成功,那么就会返回0, 如果返回失败就返回一个非0的值。

其第一个参数是我们要定位光标的流,第二个参数是偏移量,第二个参数要看我们第三个参数来定。

然后第三个参数可以取下面的三个值:

当其取SEEK_SET的时候,光标的偏移量要从文件的头部开始计算,当其为SEEK_CUR的时候,那么光标的偏移量要从当前光标的位置开始计算,当这个值为SEEK_END的时候,那么光标的偏移量就要从尾部开始计算。

下面我们通过一个例子来理解:

我们一个文件存储着hello五个字符,然后我们此时的光标在h后面的这个位置,然后我们要获取第四个位置的字符,那么我们就要将这个光标移动到第四个字符前面的位置。但是我们要看第三个参数的值是什么才可以确定这个偏移量。

当origin的值为SEEK_SET的时候,那么我们的光标就要从头开始移动,那么我们此时的光标的偏移量应该为3才可以。

当origin的值为SEEK_CUR的时候,那么我们的光标就是从当前的位置开始计算,那么我们此时的偏移量应该为2。

当origin的值为SEEK_END的时候,那么我们的光标就会从尾部开始计算,那么我们此时的偏移量应该为-2。

所以第二个参数的值要看第三个参数的值来决定。

下面我们通过代码来实际操作:

上面这个程序,首先我以文本写的方式打开了这个文件,然后我们使用fputs函数对这个文件进行写入一个字符串,然后我们使用fseek函数对其进行随机读写,首先我们看第三个参数,此时我们的第三个参数是SEEK_SET,那么此时我们是从头开始计算偏移量,然后我们第二个参数是我们此时的偏移量,那么我们的是9,那么就使得光标此时移动到偏移量为9的位置,那么此时的光标就在n的位置的前,那么我们再使用fputs函数,从这个位置对其进行写入,我们这个写入是会将原来的内容覆盖的,还有就是空白符也是一个位置的,然后我们就将原来的内容进行修改了。

下面我们运行代码看看文件修改后的内容:

可以看到我们文件的内容就被修改成这样了。

但是我们发现这个函数还是有点不方便,就是这个偏移量的计算,如果我们一个一个数非常不方便,还有就是我们有时对于空白的地方是几个位置是不好数的。那么有没有啥是可以帮助我们计算在这个偏移量的?

下面我们就学习这个可以帮助我们计算偏移量的函数:ftell函数。

2、ftell函数 

这个函数的作用就是将当前光标的位置到文件开头的偏移量返回。

原型:

long int ftell(FILE*stream);

其还是原型还是很简单的,其参数就是我们要进行操作的流,然后返回值是一个长整型,返回值就是当前这个文件的光标到开头的偏移量。

我们来使用这个函数来看看其使用效果:

运行结果:

 

我们先来分析一下上面的代码,首先我们以文本读的方式打开这个文件,然后我们将这个光标移动到这个文件的尾部,然后我们使用ftell函数计算当前的光标的位置到文件头部的偏移量,那么得到的就是我们这个文件内容的字节数,刚刚好是16个字节。

3、rewind函数 

这个函数的功能就是将文件中的指针回到开始的位置,也就是将这个光标重新回到开头处。

原型:

void rewind(FILE*stream);

它的参数就是我们要进行操作的流,其功能就是将文件中的光标移动到开头。

下面我们使用这个函数:

下面我们分析一下这段代码:

我们首先以读写的方式打开这个文件,然后我们使用一个循环,将大写字母A~Z的字符写入到我们的文件中,此时我们的文件的光标就应该在尾部了,然后我们再使用rewind函数,那么此时我们的光标就处于开头处了,然后我们又使用fread函数将这个文件的内容读取出来,存放在字符数组buffer中,然后我们关闭这个文件,将这个数组的内容打印出来:

运行结果:

 

可以发现这个数组存放的内容就是文件的内容。

不过上面还有一个问题就是,fread函数是对二进制文件进行操作的,那么我们通过上面的例子就可以发现,这个函数对于文本文件也是可以读取文本文件的。

那么fwite函数其实也可以对文本文件进行操作的。

二、文本读取结束的判断

1、被错误使用的feof

牢记:在文本读取中,不能使用feof函数的返回值来直接判断文本的读取是否结束。

feof函数的作用是当文件读取结束的时候,判断的是读取结束的原因,是否是读取到结尾结束。

那么其使用的前提是:文件读取已经结束了。

2、判断文件读取结束的方法

我们对于不同的文件,有其对应的方法:

(1)文本文件

根据我们的读取函数的返回值来确定,前面我们学习的到了文件读取的函数。

判断fgetc函数的返回值是否为EOF

判断函数fgets的返回值是否为NULL

(2)二进制文件

freacd函数判断返回值是否小于实际要读的个数。

3、判断文件读取结束的原因

我们上面学习了判断文件读取结束的方法,那么就是说,文件读取结束不一定就是正常的,那么有那些错误读取结束呢?

首先正常读取是文件读取到了文件的末尾处。

错误读取就是因为某种原因导致文件读取中途就结束了读取。

我们判断读取是否正常就使用feof函数和ferror函数。

feor这个函数我们上面已经介绍过了。

其原型如下:
int feof(FILE*stream);

ferror函数是在文件读取结束后,用来判断文件是否是错误读取结束,其原型如下:

int ferror(FILE*stream);

它是参数是要操作的流,如果文件是错误读取结束,那么就返回一个非0值,如果没有错误结束,那么就返回0

下面我们通过实例来理解:

那么在上面我们使用一个循环对这个文件进行读取,然后使用feof函数进行判断,如果其返回值是非0值,那么就说明其是非正常结束,如果是0那么就说明是正常结束。

三、文件缓冲区 

我们在对文件进行写入操作的时候,这时候如果我们点进这个文件看的时候,我们写入的内容并不是立马就在文件中出现的,而我们关闭文件后,再重新打开这个文件,此时就可以在文件中找到我们写入的内容了。

这就得知道我们的文件缓冲区的内容了。

ANSIC标准采⽤“缓冲⽂件系统”处理的数据⽂件的,所谓缓冲⽂件系统是指系统⾃动地在内存中为 程序中每⼀个正在使⽤的⽂件开辟⼀块“⽂件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓 冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读⼊数据,则从磁盘⽂件中读取数据输 ⼊到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓 冲区的⼤⼩根据C编译系统决定的。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2325794.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CCCC天梯赛L1-094 剪切粘贴

题目链接: 字符串函数: 1、截取字符串: //起始位置为3,结束位置为5string s "aabcdefg";//下标从0开始 [从开始位置,结束位置]string sub s.substr(3,3);//输出cde, 有返回值string//并且原字符串不改变, s"aab…

某地81栋危房自动化监测试点项目

1. 项目简介 房屋进入老龄化阶段后,结构安全风险越来越大。近10年来,每年都会产生房屋倒塌人员伤亡的重大安全事故。调研分析显示,老旧房屋结构安全风险管理的有效路径为,通过“人防技防”的组合模式,对房屋安全风险进…

远程装个Jupyter-AI协作笔记本,Jupyter容器镜像版本怎么选?安装部署教程

通过Docker下载Jupyter镜像部署,输入jupyter会发现 有几个版本,不知道怎么选?这几个版本有什么差别? 常见版本有: jupyter/base-notebookjupyter/minimal-notebookjupyter/scipy-notebookjupyter/datascience-notebo…

山东大学软件学院项目创新实训开发日志(4)之中医知识问答数据存储、功能结构、用户界面初步设计

目录 数据库设计: 功能设计: 用户界面: 数据库设计: --对话表 (1个对话包含多条消息) CREATE TABLE conversations ( conv_id VARCHAR(36) PRIMARY KEY, -- 对话ID user_id VARCHAR(36) NOT NULL, -- 所属用户 title VARCHAR(100), -- 对话…

20.思科交换机二层链路聚合的详细配置命令解析

思科交换机二层链路聚合的详细配置命令解析 一、PAgP协议的配置SW1的配置SW2的配置二、LACP标准协议三、配置聚合组的带宽和速率四、确保所有接口的双工模式和速率一致五、故障排除和监控在Cisco设备上配置链路聚合(也称为端口通道或EtherChannel)可以增强网络连接的带宽和可…

【多线程】单例模式和阻塞队列

目录 一.单例模式 1. 饿汉模式 2. 懒汉模式 二.阻塞队列 1. 阻塞队列的概念 2. BlockingQueue接口 3.生产者-消费者模型 4.模拟生产者-消费者模型 一.单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,其核心思想是确保…

Qt5.14.2+Cmake使用mingw64位编译opencv4.5成功图文教程

​ 一、下载安装相关编译环境软件 1.1 Python3.8:安装路径:C:\Users\Administrator\AppData\Local\Programs\Python\Python38-32 安装包:python3.8.exe 1.2 QT5.14.2:安装路径:C:\Qt\Qt5.14.2 1.3 opencv4.5:解压路径D:\o…

Mamba4D阅读

CVPR 2025 创新 基于transformer的4D主干由于其二次复杂度而通常存在较大的计算成本,特别是对于长视频序列。 开发了帧内空间Mamba模块,建立时空相关性。 GPU占用和速度很有优势。 代码还没发。 Pipeline 输入点云序列,根据超参数构建点管…

手工排查后门木马的常用姿势

声明!本文章所有的工具分享仅仅只是供大家学习交流为主,切勿用于非法用途,如有任何触犯法律的行为,均与本人及团队无关!!! 1. 检查异常文件 (1)查找最近修改的文件 # 查…

算法导论(动态规划)——简单多状态

算法思路(17.16) 状态表示: 在处理线性动态规划问题时,我们可以通过“经验 题目要求”来定义状态表示。通常有两种选择: 以某个位置为结尾的情况;以某个位置为起点的情况。 本题中,我们选择更常…

LeetCode 438. 找到字符串中所有字母的异位词

438. 找到字符串中所有字母的异位词 题目描述 给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。 输入输出示例及数据范围 思路 这道题的思路其实很简单,就是一个滑动窗口的裸题&a…

java详细笔记总结持续完善

一.Java开发环境的搭建 1. 单位换算 1TB 1024GB 1GB 1024MB 1MB 1024KB 1KB 1024Byte (字节) 1Byte 8 bit(位) 注意:一个字节占8位 2. DOS命令 DOS : Disk Operation System 磁盘操作系统 即用于操作本地磁盘的系统 命令操作符号盘符切换命令盘符名:查看当前文…

wsl2的centos7安装jdk17、maven

JDK安装 查询系统中的jdk rpm -qa | grep java按照查询的结果,删除对应版本 yum -y remove java-1.7.0-openjdk*检查是否删除 java -version 下载JDK17 JDK17,下载之后存到wsl目录下(看你自己)然后一键安装 sudo rpm -ivh jd…

乐鑫ESP-Mesh-Lite方案,启明云端乐鑫代理商,创新组网拓展智能应用边界

在当今智能化浪潮的背景下,智能家居、智能农业、能源管理等领域对设备组网的需求日益增长。然而,传统的Wi-Fi组网方式常常受限于设备数量、路由器位置以及网络覆盖范围等因素,难以满足复杂场景下的多样化需求。 一方面,需要支持更…

ISIS【路由协议讲解】-通俗易懂!

IS-IS的背景 IS-IS最初是国际标准化组织ISO为它的无连接网络协议CLNP(ConnectionLess Network Protocol)设计的一种动态路由协议。随着TCP/IP协议的流行,为了提供对IP路由的支持,IETF在相关标准中对IS-IS进行了扩充和修改&#xf…

Vitis HLS 学习笔记--块级控制(IDE 2024.1 + 执行模式 + 默认接口实现)

目录 1. 简介 2. 默认接口实现 2.1 执行模式 2.2 接口范式 2.2.1 存储器 2.2.2 串流 2.3.3 寄存器 2.3 Vitis Kernel Flow 2.3.1 默认的协议 2.3.2 vadd 代码 2.3.3 查看报告 2.4 Vivado IP Flow 2.4.1 默认的协议 2.4.2 vadd 代码 2.4.3 查看报告 3. 测试与波…

红宝书第二十一讲:详解JavaScript的模块化(CommonJS与ES Modules)

红宝书第二十一讲:详解JavaScript的模块化(CommonJS与ES Modules) 资料取自《JavaScript高级程序设计(第5版)》。 查看总目录:红宝书学习大纲 一、模块化的意义:分而治之 模块化解决代码依赖混…

github 页面超时解决方法

github 页面超时解决方法 每次好不容易找到github项目代码之后,满心欢喜打开却是个无法访问,心顿时又凉了半截,现在有方法可以访问github啦 快来学习 打开浏览器插件(Edge浏览器) 搜索iLink插件 并安装 打开插件 填…

前端 vue 项目上线前操作

目录 一、打包分析 二、CDN加速 三、项目部署 1. 打包部署 2. nginx 解决 history 刷新 404 问题 3. nginx配置代理解决生产环境跨域问题 一、打包分析 项目编写完成后,就需要部署到服务器上供他人访问。但是在此之前,我们可以先预览项目的体积大…

vue: easy-cron扩展-更友好地显示表达式

我们一个批处理调度系统里要用到cron表达式,于是就在网上找到一个现成的组件easy-cron,采用后发现,它的配置界面还是很直观的,但显示时直接显示cron表达式,这对业务人员很不友好,所以,我们就扩展…