C语言文件操作(3)

news2024/9/28 23:25:36

TIPS

1. 文件是不是二进制文件,不是后缀说了算,而是内容说了算

2. 


文件的随机读写

文件的随机读写也就是说我指哪打哪

fseek()   人为调整指针指向的位置 

 

1. 根据文件指针FILE*的当前位置和你给出的偏移量来让它这个文件指针呢定位到你想要的位置上去
2. 就是说我想让文件指针偏移到哪里,你就给我偏移到哪里
3. 它这个函数有三个参数:FILE* stream,long int offset(偏移量),int origin(起始位置)
4. 其中第三个参数int origin是有选项的。关于这个参数有三个选项:SEEK_SET,就是说从文件的起始位置开始算起;SEEK_CUR,从当前文件指针的位置算起;SEEK_END,就是说从文件的末尾开始算起。


补充:文件指针的正常运走

1. 一旦打开文件,有个闪烁的光标(其实就是说刚开始打开文件的时候,文件指针是默认指向第一个字符的),这是最开始的状态
2. 然后当你用fgetc()输入一个字符后,此时文件指针就不指向第一个字符了,往后走一步指向第二个字符去了
3. 再用fgetc()不断去读,文件指针就不断往后偏移,一个一个字符不断读下去。这就是顺序读写,那如果说你想控制顺序跳过字符或者回去读之类的.....


5. 这时候就用fseek去手动调整指针指向的位置,有三种写法。随着你第三个参数的不同,偏移量也不同(往左偏移,偏移量为负数;往右偏移,偏移量为正数)。
6. 然后不管你怎么去调整,默认的"读一下,往右偏移一个字符"这个铁律永远都在。但不管怎么说,fseek就是能调整指针指向的位置,读一位的话往右偏移一位那就让它偏呗。 

//演示fseek()
int main()
{
	FILE* pf = fopen("test.txt","r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int ch = 0;
	//正常
	ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	//调整1
	fseek(pf, 7, SEEK_SET);
	ch = fgetc(pf);
	printf("%c", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	//调整2
	fseek(pf, -5, SEEK_END);
	ch = fgetc(pf);
	printf("%c", ch);
	ch = fgetc(pf);
	printf("%c", ch);
	ch = fgetc(pf);
	printf("%c", ch);
	ch = fgetc(pf);
	printf("%c\n", ch);
	//
	fclose(pf);
	pf = NULL;
	return 0;
}

 

 


ftell()     当前指针位置相当于起始位置的偏移量

 

1. 如果我用fseek()的时候,里面内容很多,我弄着弄着也不知道偏移量多少了怎么办?
2.ftell就是来返回当前文件指针相对于起始位置的偏移量。这样子你可以得到偏移量,然后用fseek乱弄了。

//演示ftell()
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int ch = 0;
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		fgetc(pf);
	}
	//计算当前偏移量
	int a = ftell(pf);
	//调整
	fseek(pf, 7 - a, SEEK_CUR);
	//
	for (i = 0; i < 9; i++)
	{
		fprintf(stdout, "%c", fgetc(pf));
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

 

 


rewind()       让指针回到起始位置

 

1. 让我们的文件指针回到起始位置,当然了,fseek本身就具备这个能力。然而rewind也可以做到。 

//演示rewind()
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int ch = 0;
	int i = 0;
	for (i = 0; i < 3; i++)
	{
		fgetc(pf);
	}
	rewind(pf);
	//
	for (i = 0; i < 16; i++)
	{
		fprintf(stdout, "%c", fgetc(pf));
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

 

 


文本文件与二进制文件

1. 根据数据的组织形式,数据文件(与它同级的是程序文件)又被称为文本文件二进制文件
2. 我们知道,数据在电脑内存里面是以二进制补码形式存储如果对内存里面的数据(纯纯的二进制)不加任何转换输出到外存(比如说输出到硬盘上啊文件里面去,反正就是写到文件里面去),这个时候就叫做二进制文件。
3. 如果要求在外存上以ASCII码值的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件。(把字符对应的ASCII码值存到文件里面去,以ASCII码值的形式存储)。
4. 当然,这里面还有一个大小端的问题,如果你在内存里面以小端形式存储,那么也会直接以小端的形式写到文件里面去

实例演示 

1. 比如说对于一个数值10000。如果我要把它存起来。我们知道这个10000在内存里面就是00......0010011100010000。如果说我们把这个二进制序列不做任何转换直接存到文件里面去,此时这个文件就是二进制文件。
2. 如果说我们把10000的每一位都当成字符即:"1","0","0","0","0"。然后把每个字符对应的ASCII码值存到文件里面去。这时候这个文件就是文本文件。  

 

 


文件读取结束/读取失败or碰到EndOfFile 

1. 这个是读取文件的时候非常非常重要的知识点。
2. 我们不管用前面讲的哪个函数fgetc,fgets,fread,fscanf...,这些都是在读取文件。一般来说都是正常的,比如fgetc()返回ASCII值,fgets()返回字符串地址,fread()返回读到的实际元素个数

3. 但是有时候问题来了,fgetc()返回EOF,fgets()返回NULL,fread()返回读到的实际元素个数<我参数指定的元素个数,这时候就是读取文件结束

文件读取结束

对于文本文件的读取(fgetc,fgets):对于fgetc()如果读取结束就会返回EOF,对于fgets()如果读取结束就会返回NULL(空指针)。
对于二进制文件的读取(fread):fread我们知道在使用的时候我会在参数指定我要读取几个元素,每个元素几个字节。但实际上比如说我参数指定了读9个元素,但它只读到了8个,这时候就会返回8,就是说它的返回值是你实际读到几个就返回几。所以我只需要去判断一下fread的返回值是否小于参数指定的要读的个数,我就能知晓是否文件已经读取结束。

文件的读取结束之后,接下来就需要我去判断一下读取结束的原因。是因为碰到了文件末尾结束,还是因为读取失败而导致结束

前提:文件读取结束了,想知道读取结束的原因.....
feof()与ferror()是用来判断结束原因的

ferror()          判断是不是碰到了异常错误导致读取结束

 

1. 判断这个文件结束的原因是不是因为读取的时候碰到了错误。
2. ferror()如果返回真,就说明是因为IO错误结束的(也就是说文件在读取过程中出错了),这是一种外因异常结束。

feof()    判断是不是碰到了文件结尾而正常读取结束

 

1. 可以用它去判断一下。
2. feof()如果返回真,就说明文件正常读取,在读取的时候碰到文件结束标志EOF而结束的。

 


文件缓冲区

 

1.  ANSIC标准采用“缓冲文件系统”来处理数据文件
2. 所谓“缓冲文件系统”,指系统自动地在内存中为程序中正在运行的每一个文件开辟一块“文件缓冲区”。
(文件就是在电脑磁盘里面)
3. 内存数据输出/写到磁盘里面,其会先被送到内存中的输出缓冲区,装满缓冲区后再一次性送到磁盘里面/或者说我主动刷新一下缓冲区里面的数据然后放到硬盘里面去
(然后假设我缓冲区一直没满,但是我要关闭文件了,这时候没关系,系统会刷新一份缓冲区的数据,这时候不管满没满了,文件都要关闭了,直接把数据放到文件里面去,然后才关闭文件,所以fclose本身关闭文件的时候也会刷新缓冲区的
4. 如果从磁盘里面往内存输入/读数据,数据也是先放到缓冲区。充满缓冲区后,然后再从缓冲区里面逐个地将数据送到程序数据区(程序变量等)。
5. 缓冲区大小根据C编译系统决定。
6. 缓冲区也是在内存里面的,当然了,摸不着看不到的。

 

证明缓冲区的存在

 

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

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

相关文章

Flutter 这一年:2022 亮点时刻

回看 2022&#xff0c;展望 Flutter Forward 2022 年&#xff0c;我们非常兴奋的看到 Flutter 社区持续发展壮大&#xff0c;也因此让更多人体验到了令人难以置信的体验。每天有超过 1000 款使用 Flutter 的新移动应用发布到 App Store 和 Google Play&#xff0c;Web 平台和桌…

实战打靶集锦-002-SolidState

**写在前面&#xff1a;**谨以此文纪念不完美的一次打靶经历。 目录1. 锁定主机与端口2. 服务枚举3. 服务探查3.1 Apache探查3.1.1 浏览器手工探查3.1.2 目录枚举3.2 JAMES探查3.2.1 搜索公共EXP3.2.2 EXP利用3.2.2.1 构建payload3.2.2.2 netcat构建反弹shell3.2.3 探查JAMES控…

三十一、Kubernetes中Service详解、实例第一篇

1、概述 在kubernetes中&#xff0c;pod是应用程序的载体&#xff0c;我们可以通过pod的ip来访问应用程序&#xff0c;但是pod的ip地址不是固定的&#xff0c;这也就意味着不方便直接采用pod的ip对服务进行访问。 为了解决这个问题&#xff0c;kubernetes提供了Service资源&…

NX二开ufun函数UF_MODL_ask_curve_points(获取曲线信息)

根据曲线tag&#xff0c;返回曲线相关信息&#xff1a;弦宽容、弧度、最大步长、点数组的点。 实例返回结果截图如下&#xff1a; 实例创建曲线截图如下&#xff1a; 1、函数结构 int UF_MODL_ask_curve_points &#xff08;tag_t curve_id&#xff0c; double ctol&#xf…

【SpringCloud19】SpringCloud Alibaba Sentinel实现熔断与限流

1.概述 官网 中文文档 1.1 是什么 一句话解释&#xff0c;之前我们讲解过的Hystrix 1.2 怎么下 下载网址 1.3 作用 1.4 如何使用 官网学习 服务使用中的各种问题&#xff1a; 服务雪崩服务降级服务熔断服务限流 2.安装Sentinel控制台 2.1 组成部分 核心库&#x…

Golang之实战篇(1)

"千篇一律&#xff0c;高手寂寞。几十不惑&#xff0c;全都白扯"上篇介绍了golang这门新的语言的一些语法。那么我们能用golang简单地写些什么代码出来呢&#xff1f;一、猜数字这个游戏的逻辑很简单。系统随机给你生成一个数&#xff0c;然后读取你猜的数字&#xf…

老杨说运维 | AIOps如何助力实现全面可观测性(上)

前言&#xff1a; 嗨&#xff0c;今天是大年三十&#xff0c;大家是不是已经在家坐享团圆之乐了&#xff1f;还是说在奔向团圆的路上呢&#xff1f;不论如何&#xff0c;小编先祝大家新年如意安康&#xff0c;平安顺遂~ 熟悉我们的朋友肯定都知道&#xff0c;关于《老杨说运维…

30.字符串处理函数

文章目录1.测字符串长度函数2.字符串拷贝函数1.strcpy函数2.strncpy函数3.字符串追加函数1.strcat函数2.strncat函数4.字符串比较函数1.strcmp函数2.strncmp函数5.字符查找函数1.strchr函数2.strrchr函数6.字符串匹配函数7.空间设定函数8.字符串转换数值9.字符串切割函数strtok…

【Java开发】Spring Cloud 04 :服务治理Nacos

本章节正式进入 Spring Cloud 环节了&#xff0c;首先介绍微服务架构中一个最重要的原理概念&#xff1a;服务治理&#xff0c;在概念讲解之后&#xff0c;讲解介绍 Nacos 服务注册中心的体系结构。1 服务治理1.1 服务治理介绍首先通过一个例子告诉你服务治理解决了什么问题。比…

GD32F4——外部中断

一、NVIC中断系统 Cortex-M4集成了嵌套式矢量型中断控制器&#xff08;Nested Vectored Interrupt Controller&#xff0c;NVIC&#xff09;来实现高效的异常和中断处理。 中断系统包含外部中断、定时器中断、DMA中断和串口中断等。 二、EXTI外部中断 EXTI&#xff08;中断…

go的基本语法介绍之变量的声明与初始化

1.常见基本数据类型 uint8&#xff1a;无符号8位整形&#xff0c;取值范围&#xff1a;0-255 uint16&#xff1a;无符号16位整形&#xff0c;取值范围&#xff1a;0-65535 uint32&#xff1a;无符号32位整形&#xff0c;取值范围&#xff1a;0-4294967295 uint64&#xff1…

opencv arm交叉编译与仿真验证详细流程

【关键内容】 1.将opencv编译为能在arm上运行的库 2.在没有板子的情况下&#xff0c;仿真验证opencv库 1.将opencv编译为能在arm上运行的库 1.在下方链接中选择某个版本 Releases - OpenCVhttps://opencv.org/releases/点击“Sources”即可开始下载&#xff0c;得到opencv-…

「数据结构、逻辑结构、物理结构」基本概念简析

前言 前言&#xff1a;简析数据结构、逻辑结构、物理结构。 文章目录前言一、数据结构1. 简介2. 数据3. 结构4. 分析5. 分类1&#xff09;线性结构&#xff08;线性表&#xff09;2&#xff09;树结构3&#xff09;图结构二、逻辑结构与物理结构1. 为什么要有逻辑结构和物理结构…

【leetcode合集】如何知道自己是否掌握了数组与链表?试试这几道题目吧!

目录 1.数组题目合集 1.1 leetcode.27 移除元素 1.2 leetcode.26 删除有序数组中的重复项 1.3 leetcode.88 合并两个有数数组 2.链表题目合集 2.1 leetcode.203 移除链表元素 2.2 leetcode.206 反转链表 2.3 leetcode.876 链表的中间结点 2.4 牛客 链表中倒数第k个结点…

零基础学JavaWeb开发(十七)之 mybatis(2)

5、MyBatis - 映射文件标签 5.1、映射文件的顶级元素 select&#xff1a;映射查询语句 insert&#xff1a;映射插入语句 update&#xff1a;映射更新语句 delete&#xff1a;映射删除语句 sql&#xff1a;可以重用的 sql 代码块 resultMap&#xff1a;最复杂&#xff0c…

章鱼网络 2022 虎年全回顾

全长5606字&#xff0c;预计阅读20分钟2022年对章鱼网络而言颇为特别。这是章鱼网络建设应用链多链生态历程的第一年&#xff0c;整个 Web3 行业都经历了极其糟糕的市场环境&#xff0c;但是我们在「生态建设」、「基础设施优化」、「社区治理」和「市场拓展」等都有长足进展&a…

31.Isaac教程--规划器代价

规划器代价 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 文章目录规划器代价组件入门通过应用程序图自定义成本导航本地规划器基于线性二次调节器 (LQR) 规划器。 它通过生成最小化成本函数的轨迹来工作。 不幸的是&#xff0c;没有适用于所有…

Allegro如何输出第三方网表操作指导

Allegro如何输出第三方网表操作指导 在做PCB设计的时候,会需要输第三方网表,Allegro支持快速输出第三方网表,如下图 具体操作如下 选择File选择Export

Leetcode:39. 组合总和、40. 组合总和 II(C++)

目录 39. 组合总和&#xff1a; 问题描述&#xff1a; 实现代码与解析&#xff1a; 回溯&#xff1a; 原理思路&#xff1a; 剪枝版&#xff1a; 40. 组合总和 II&#xff1a; 问题描述&#xff1a; 实现代码与解析&#xff1a; 回溯&#xff1a; 原理思路&#xff…

函数——“C”

各位CSDN的uu们新年快乐呀&#xff0c;祝大家越来越开心&#xff0c;越来越优秀。那行&#xff0c;让我们进入今天的正题&#xff0c;来了解了解函数&#xff0c;函数是什么&#xff0c;C语言中函数是如何分类的&#xff0c;函数参数&#xff0c;函数调用等一系列小知识点&…