【C语言】文件操作(终卷)

前言

我们在上一卷中了解了顺序读写的函数,现在就让我们从随机读写的函数开始吧。

什么是随机读写?

就是想在哪个位置读或写都行,比较自由。文件打开时光标默认在起始位置。想从后面的某个部分读或写,就得让文件指针来到那个位置:

fseek函数

这个函数就能根据文件指针的位置和偏移量来定位文件指针(文件内容的光标,不是指FILE*类型的文件指针)。

 这个函数有3个参数,第一个是文件指针,第二个是偏移量,第三个指的是起始位置。毕竟,要给出从哪开始,偏移量是多少,才能随机读写。

 注意,offsetof可以为负数

最后一个参数origin有三种选项

第一个是文件的起始位置;第二个是文件指针(光标)当前的位置;第三个是文件的末尾。

请看下面的代码: 

 可以看到我们用fgetc两次读文件时,第一次结果是a,第二次是b,这说明什么?说明第二次读的时候我们的光标向后一移了一个字符。

 光标是一个个移动的,如果我们现在想直接读到e,就不能使用这种方式。

使用fseek定位到起始位置偏移量为4的位置也就是指向e的位置,再读,就得到了e。

 或者我们最后一个参数使用SEEK_END:

或者SEEK_CUR:

 

ftell函数

返回文件指针相较于起始位置的偏移量:

当我们读文件不知道读到哪了,偏移量是多少,就可以使用它。

我们分析一下偏移量为5:

 e读完后其实光标会移动到e的后一位也就是指向f。所以读完e算偏移量,就是5。

rewind函数

让文件指针的位置回到文件的起始位置。

我们使用完再读就是a:

文件结束的判定

被误解的函数 feof

EOF——end of file 文件结束标志

所以很多人以为feof是用来判断文件是否结束的。

实际上,它的作用是当文件读取结束的时候,判断读取结束的原因是否是遇到文件结尾。

在读取文件的过程中可能读取结束,结束的原因可能是确实遇到了文件末尾(读完了),也可能遇到了错误。那么为了判断,我们就可以使用feof。

feof负责判断是否是因为遇到文件末尾而结束的。而不是判断是否读取结束。

那么怎么判断是否读取结束呢?对于文本文件而言,用fgetc正常读到字符返回的是读到字符的ASCII码值,失败或读取结束会返回EOF;用fgets判断的话(一行一行读),读取失败或者读取结束返回NULL。 所以用fgetc去读判断是否为EOF,用fgets去读判断返回值是否为NULL,就能知道是否读取结束; 

而如果是以二进制的形式去读,返回值小于实际要读的个数就是读取结束的标志。(讲fread时提到过:参数count是一次读几个,如果返回值比num小,说明读取结束)

文本文件判定读取结束原因例子:

二进制文件判定读取结束原因的例子:

注意:没有读到文件结尾时,没有任何状态值被设置,feof的返回值会是0;如果读到文件末尾,返回非零值(一般为1)。

那ferror呢?没有错误时返回0,有错误时返回非零值(1)。那么什么时候会错呢?比如要写文件却以"r"打开文件,要读文件却以"w"形式打开,就会ferror返回1(但是这种情况perror打印不了正确的错误信息,可以自己编写一个错误信息)

 可以看到返回值部分的描述和feof是非常相似的。

文件缓冲区

程序数据区和硬盘之间的输入、输出并不是直接进行的,而是在中间还有一个文件缓冲区:

ANSIC标准采用“缓冲文件系统”处理数据⽂件,所谓缓冲文件系统是指系统自动地在内存中为程序中每⼀个正在使用的文件开辟⼀块“文件缓冲区”。

从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才⼀起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小是根据C编译系统决定的。

为什么要有文件缓冲区?

这就像你去找老师提问,一遇到一个问题就跑去问老师,一分钟去一次,老师时间就会被你占用,只能给你一个人解答;但如果你攒够多个问题再一起提问,老师就能腾出时间做别的事。

所以我们也不是有一个数据就写到硬盘上的,写数据不是直接就能写上去的,还要调用操作系统的接口,如果我们一有数据就写,总是打断操作系统;现在有了缓冲区,充满了再写入硬盘,操作系统就能做其他事,提高了效率。

观察缓冲区例子:

注意,第二次Sleep是因为文件关闭时也会刷新缓冲区,为了保证缓冲区的刷新不是因为关闭文件,延缓关闭文件。 

所以我们得出一个结论

因为有缓冲区的存在,C语言在操作文件时,需要刷新缓冲区或在文件操作结束时关闭文件,如果不这样做,可能导致读写文件的问题。

到此,文件操作的内容就结束了,祝阅读愉快^_^

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

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

相关文章

VMware Fusion 如何增加linux硬盘空间并成功挂载

文章目录 0. 前言1. 增加硬盘空间2. 硬盘分区2.1 查看硬盘2.2 分区2.3 格式化2.4 挂载 3. 参考 0. 前言 如果发现虚拟机分配的硬盘不足,需要增加硬盘空间。本文教给大家如何增加硬盘空间并成功挂载。 查看当前硬盘使用情况: df -h可以看到&#xff0c…

什么是档案数字化管理

档案数字化管理指的是将传统的纸质档案转换为数字形式,并通过电子设备、软件和网络技术进行管理和存储的过程。 档案数字化管理包括以下几个步骤: 1. 扫描和数字化:将纸质档案通过扫描仪转换为数字图像或文档。可以使用OCR(光学字…

[数据集][图像分类]人种黄种人白人黑人分类数据集970张4类别

数据集类型:图像分类用,不可用于目标检测无标注文件 数据集格式:仅仅包含jpg图片,每个类别文件夹下面存放着对应图片 图片数量(jpg文件个数):970 分类类别数:4 类别名称:[“Asian”,“Caucasian”,“Indian…

什么是 AOF 重写?AOF 重写机制的流程是什么?

引言:在Redis中,持久化是确保数据持久性和可恢复性的重要机制之一。除了常见的RDB(Redis Database)持久化方式外,AOF(Append Only File)也是一种常用的持久化方式。AOF持久化通过记录Redis服务器…

基于Gabor小波特征提取和PSO-SVM的胃溃疡分类(MATLAB R2018a)

Gabor滤波器是在测不准原则下能够在时域和频域中唯一能取得最佳的联合分辨率函数(测不准原则:是指在时域与频域中都要获得任何的测量精度那是不可能同时实现的,要使时域分辨率有所提高,必须牺牲频域的分辨率,反之亦然&…

Java | Leetcode Java题解之第134题加油站

题目&#xff1a; 题解&#xff1a; class Solution {public int canCompleteCircuit(int[] gas, int[] cost) {int n gas.length;int i 0;while (i < n) {int sumOfGas 0, sumOfCost 0;int cnt 0;while (cnt < n) {int j (i cnt) % n;sumOfGas gas[j];sumOfCos…

Polar Web【中等】search

Polar Web【中等】search Contents Polar Web【中等】search思路&探索首页一般注入方式 EXP&效果Payload 总结 思路&探索 见到题目标题&#xff0c;预测可能有目录扫描或者输入框查询数据之类情况&#xff0c;具体细节在破解过程中才能清楚 打开站点&#xff0c;显…

如何下载BarTender软件及详细安装步骤

BarTender是美国海鸥科技推出的一款优秀的条码打印软件&#xff0c;应用于 WINDOWS95 、 98 、 NT 、 XP 、 2000 、 2003 和 3.1 版本&#xff0c; 产品支持广泛的条形码码制和条形码打印机&#xff0c; 不但支持条形码打印机而且支持激光打印机&#xff0c;还为世界知名品牌条…

前端-a-date-picker如何设置禁选时间段

想要做到如图所示的效果&#xff0c;代码如下&#xff1a; 第一个是只能选择某一天&#xff0c;第二个是只能选择某一个时间段 <a-date-pickerv-model:value"record.onTimeStr":show-time"{ format: HH:mm }"valueFormat"YYYY-MM-DD HH:mm:ss&qu…

【RAG入门教程02】Langchian的Embedding介绍与使用

Embedding介绍 词向量是 NLP 中的一种表示形式&#xff0c;其中词汇表中的单词或短语被映射到实数向量。它们用于捕获高维空间中单词之间的语义和句法相似性。 在词嵌入的背景下&#xff0c;我们可以将单词表示为高维空间中的向量&#xff0c;其中每个维度对应一个特定的特征…

mm-qcamera-daemon主函数分析

目录 main函数核心 main函数核心 main函数的主要任务包含在一个do{ } while(1)循环中. while循环中主要是监听文件描述符,故mai函数是由文件的读写来进行驱动的。 所有的文件描述符被封装成结构体 read_fd_info_t.其定义如下&#xff1a; /** read_fd_info_t* type -- either …

拯救者Legion Y9000X IRX9 2024(83FD)原装出厂Windows11系统镜像下载

lenovo联想2024款拯救者Y9000X IRX9 笔记本电脑【83FD】OEM预装Win11系统安装包&#xff0c;恢复开箱状态&#xff0c;自带恢复重置还原功能 链接&#xff1a;https://pan.baidu.com/s/1i_sVcnXF4qgsuj02rebe-Q?pwdyefp 提取码&#xff1a;yefp 联想原装WIN11系统自带所有…

Vue2学习(04)

目录 一、组件的三大组成部分 二、组件的样式冲突scoped 三、scoped原理 ​编辑 四、data是一个函数 五、组件通信 1.概念&#xff1a;是指组件与组件之间的数据传递&#xff0c;组件的数据是独立的&#xff0c;无法直接访问其他组件的数据&#xff0c;想用其他组件的数…

Pycharm中import torch报错解决方案(Python+Pycharm+Pytorch cpu版)

pycharm环境搭建完毕后&#xff0c;编写一个py文件demo&#xff0c;import torch报错&#xff0c;提示没有。设置python解释器&#xff1a; 选择conda环境&#xff0c;使用现有环境&#xff0c;conda执行文件找到Anaconda安装路径下Scripts文件夹内的conda.exe&#xff0c;最后…

【Java SE】字符串常量池详解,什么情况下字符串String对象存在常量池,通过==进行判断,字符串创建及截取后是否同一个对象

复习字符串创建方式 字符串的31种构造方法 public String();创建一个空白字符串&#xff0c; 不含有任何内容public String(char[] array);根据字符数组的内容&#xff0c;来创建对应的字符串public String(byte[] array);根据字节数组的内筒&#xff0c;来创建对应的字符串 …

Docker:在DockerHub上创建私有仓库

文章目录 Busybox创建仓库推送镜像到仓库 本篇开始要学习在DockerHub上搭建一个自己的私有仓库 Busybox Busybox是一个集成了三百多个最常用Linux命令和工具的软件&#xff0c;BusyBox包含了很多工具&#xff0c;这里拉取该镜像推送到仓库中&#xff1a; 安装 apt install …

leetcode(力扣)第15题-三数之和---使用c语言双指针法,二级指针的应用

题目&#xff1a; 15. 三数之和 - 力扣&#xff08;LeetCode&#xff09; 编写过程的问题&#xff1a; 记住线索 1、对数组使用快排排序&#xff1b;2、固定 a 对 b、c 使用双指针&#xff1b;3、注意去重问题。函数返回值的类型。{1&#xff0c;2&#xff0c;-3}。结果作为…

如何获取当前dll或exe模块所在路径?

有时我们需要在当前运行的dll或exe模块中去动态加载当前模块同路径中的另一个库&#xff0c;或者启动当前模块同路径中的另一个exe程序&#xff0c;一般需要获取当前模块的路径&#xff0c;然后去构造同路径下目标模块的绝对路径&#xff0c;然后通过该绝对路径去加载或启动该目…

高速USB转串口芯片CH343

CH343封装 截止目前&#xff0c;主要封装有 SOP16: CH343G QFN16: CH343P ESSOP10: CH343K,截止24年6月未生产 CH343串口速度 最高串口速度&#xff1a; 6Mbps,比CH340的2M&#xff0c;快3倍 1、概述 参考版本&#xff1a;1E CH343 是一个 USB 总线的转接芯片&#xff0c;…

Java Web学习笔记31——Maven介绍

Maven&#xff1a;Java项目的构建工具。 Maven&#xff1a; Maven是Apache旗下的一个开源项目&#xff0c;是一款用于管理和构建Java项目的工具。 Apache软件基金会&#xff0c;成立于1999年7月&#xff0c;是目前世界上最大的最受欢迎的开源软件基金会&#xff0c;也是一个专…