C语言文件操作复习回顾(1)

news2025/9/18 2:34:31

关于流,内存数据读写铺垫的复习

  1. 打开一个文件 -> 内存里面就会创建一个对应关联的文件信息区 -> 文件信息区其实就是一个FILE类型的结构体 -> 各个结构体成员记录了该文件的种种信息 -> 结构体(文件信息区)由FILE* 结构体指针来维护 -> 有了指针,一切都好说了
  2. 输入输出/读写都是站在内存/程序的角度
  3. 任何一个C语言程序运行的时候,默认会打开三个流:stdin(标准输入), stdout(标准输出), stderr(标准错误)。stdin, stdout, stderr就是三个管理标准输入流,标准输出流,标注错误流的FILE*指针
    在这里插入图片描述
  4. 这个流的类型就是FILE这样一个结构体。这个流其实就是由我们的FILEstream指针来管理的。流相当于是一个FILE类型的结构体,然后FILE相当于是维护流的一个指针
  5. 如果说内存数据要输出到文件里面,你要去看看针对文件的流有没有被打开, 如果说内存数据要输出到网络里面,你要去看看针对网络的流有没有被打开, 如果说内存数据要输出到软盘里面,你要去看看针对软盘的流有没有被打开…
  6. 因为我写程序他的数据不可能永远都是在内存当中,我有可能需要把这个数据放到文件当中,比如说需要放到我的终端设备当中,比如说要放到网络上面,当把数据放到这些外部输出设备的时候。对于程序员而言,他不一定懂各种细节,所以说在c语言当中就抽象出了流这么一个概念。就是说不管三七二十一,直接把数据放到流上面,然后具体这些数据是怎么传到各种各样的外部输出设备是自己会分装好的。除了在c语言当中,程序它默认会打开三个流之外,如果说根据特定的需求,需要把数据传到其他各种各样的外部输出设备的话,就需要打开针对各种各样外部输出设备的一个流,然后实际上就是通过FILE*指针(结构体指针)来操作流(FILE结构体)。
  7. 我们在操作文件的时候,首先要打开文件拥有这个流。打开文件就好比打开了(没有被C语言默认打开的)针对文件的流,fopen()返回的FILE*指针与维护流的指针是一个道理
    在这里插入图片描述

利用输入输出流进行数据顺序读写(尤以文件为例)

文件里面没有整型等等,全部要么是字符,要么就是字符串,要么就是二进制,要么就是二进制信息解析成字符后的乱码

在这里插入图片描述
提醒一下:如果没有人为干预,文件指针都是自己自动动的

fputc() 一个字符输出

在这里插入图片描述
在这里插入图片描述

  1. 演示代码:
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen failed");
		return;
	}
	fputc('U', pf);
	fputc('S', pf);
	fputc('B', pf);

	fputc('U', stdout);
	fputc('S', stdout);
	fputc('A', stdout);
	fclose(pf);
	return 0;
}

fgetc() 一个字符输入

在这里插入图片描述
在这里插入图片描述

  1. 文件里面有多个字符的时候,我们用fgetc一个个去读取,此时定位文件位置的指针在fgetc每次读取完一次之后,就会后移一个字节往后走了一步指到下一个字符去了,因此fgetc一个个读取的话不需要顾虑太多,每次读取的时候只需要传参同一个FILE*结构体指针(事实上你其他的也传不了)
  2. 演示代码:
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen failed");
		return;
	}
	
	printf("%c\n", fgetc(pf));
	printf("%c\n", fgetc(pf));
	printf("%c\n", fgetc(pf));
	printf("%d\n", fgetc(pf));  //EOF  即-1

	fclose(pf);
	return 0;
}

fputs() 一行字符串输出 + 一个\n的问题注意一下

在这里插入图片描述

  1. 由于fputs针对的是一行字符串的输出,如果说多次调用fputs的话,比如说把字符串给他写到文件里面去,那么这多个字符串之间并不会默认换行,如果说想要达到换行的这个效果,那么就必须在输出每行字符串的时候,在字符串的末尾加上转义字符换行符\n
  2. 演示代码:
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen failed");
		return;
	}

	fputs("the United States Of American\n", pf);
	fputs("the United States Of American\n", pf);
	
	fclose(pf);
	return 0;
}

在这里插入图片描述

fgets() 一行字符串输入 + \n三特性

在这里插入图片描述

  1. 中间这个参数就是指从外部输出设备的字符串输入到内存当中的字符的个数,因为是把字符串从外部输出设备输入到内存,然后它这个字符串结束符\0是默认会强制占掉一个空间,所以说比如说你想要往内存当中输进来六个字符的字符串,你那个第二个参数应该要设置成7。
  2. 然后这个函数它只能处理一行,比如说这一行只有三个字符,下一行有300个字符,然后你采用这个函数fgets,那个参数设置成50,那么这个函数执行完成之后,你读进来的也只有这一行的那三个字符+换行符 共4个字符的字符串而已。
  3. 在文件当中,每一行的字符串末尾都默认带有一个换行符。需要注意几点:1. 这个换行符是一个实体的存在,什么意思呢?主要影响就在于fgets的第二个参数,如果在统计的时候在一行当中延伸到了换行符\n,那么这个换行符也是算做一个字符,也需要参与计数。2. 拷贝文件一行字符串的时候换行符也是可能会被拷贝到内存字符串当中的,这时候打印的时候就会产生效果与影响。3. 当文件指针碰到文件字符串一行当中的换行符时,文件指针自己也会去换行。但无论如何要记住:fgets永远处理的都是一行字符串,文件指针换行后不会又继续去拷贝下一行内容。
  4. 演示代码:
    在这里插入图片描述
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen failed");
		return;
	}

	char arr1[20] = { 0 };
	char arr2[20] = { 0 };

	fgets(arr1, 16, pf);
	fgets(arr2, 6, pf);

	printf("arr1 : %s", arr1);
	printf("arr2 : %s", arr2);
	fclose(pf);
	return 0;
}

在这里插入图片描述

fprintf() 格式化字符串输出 + 参照printf就可以了

在这里插入图片描述

  1. 如果用fprintf的话非常简单,就先正常按照printf去写,然后在括号最前面再加上一个参数(流指针),如:指向要写入文件的文件信息区的文件指针。这就是把格式化的信息写到文件里面去。
  2. 演示代码:
int main()
{
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen failed");
		return;
	}

	fprintf(pf, "%c %d %s\n", 'Y', 2, "我真是醉了");
	fprintf(pf, "%.3f %.1lf %s%c\n", 11.99954, 22.833, "无语了", 'Q');

	fclose(pf);
	return 0;
}

在这里插入图片描述

fscanf() 格式化字符串输入 + 文件指针换行问题不用考虑

在这里插入图片描述

  1. fscanf就是从文件里面把里面的信息拿到内存里面去。这个函数又与scanf十分相似,参数比scanf多了一个FILE*指针。
  2. 因此你先用scanf一如既往像以前那样正常写好,注意:scanf/fscanf的末尾几个参数都必须是地址形式,因为我是要把数据真真切切地读入到内存里面去,必须给我传地址!当然,数组名是首元素地址就不用&了。再在最前面加上参数:文件指针就OK了。
  3. 代码演示:
    在这里插入图片描述
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen failed");
		return;
	}

	char ch1 = 0;
	char ch2 = 0;
	int num = 0;
	char arr1[20] = { 0 };
	char arr2[20] = { 0 };
	float f1 = 0;
	double f2 = 0;


	fscanf(pf, "%c %d %s\n", &ch1, &num, arr1);

	fscanf(pf, "%f %lf %s %c\n", &f1, &f2, arr2, &ch2);

	printf("ch1: %c\n",ch1);
	printf("num: %d\n", num);
	printf("arr1: %s\n", arr1);

	printf("f1: %.2f\n", f1);
	printf("f2: %.1lf\n", f2);
	printf("arr2: %s\n", arr2);
	printf("ch2: %c\n", ch2);

	fclose(pf);
	return 0;
}

在这里插入图片描述

fread() 与 fwrite() 二进制输入输出只能针对文件流

sprintf() 随意粘连任何已有东西+自己也可以添油加醋+组成一个新的字符串(类型很自由)

int main()
{
	int num = 10;
	char ch = 'A';
	char* p1 = "我裂开了";
	float f = 12.5345;
	char* p2 = "哈哈哈哈哈";
	char arr[100] = { 0 };
	sprintf(arr, "%d%c%s   %s %f 666666我的新字符串", num, ch, p1, p2, f);
	printf("%s\n", arr);
	return 0;
}

在这里插入图片描述

sscanf() 随意从已有字符串抠来一些东西 + 放到新的变量当中(类型很自由)

int main()
{
	char arr[50] = "我哈哈哈哈哈        666    114514Q";
	char arr1[50] = { 0 };
	int num1 = 0;
	int num2 = 0;
	char ch = 0;
	sscanf(arr, "%s %d %d %c", arr1, &num1, &num2, &ch);
	printf("%s\n", arr1);
	printf("%d\n", num1);
	printf("%d\n", num2);
	printf("%c\n", ch);
	return 0;
}

在这里插入图片描述
在这里插入图片描述

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

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

相关文章

Linux -- 基础IO

文章目录1. 基础认识2. 回顾C文件接口2.1 现象一2.2 现象二2.3 fprintf()函数回顾2.4 fnprintf()函数使用2.5 "a"模式3. 系统接口3.1 open()和close()3.2 write()3.3 read()3.4 C文件接口和系统接口关系3.5 文件描述符3.6 深度理解Linux下一切皆文件3.7 FILE是什么3.…

OpenAI的ChatGPT迭代速度超乎想象

OpenAI的ChatGPT迭代速度超乎想象,被谷歌聊天机器人Bard 嘲笑“家里不通网”后,OpenAI一个鲤鱼打挺甩出“实时联网”方案。 美西时间3月23日,OpenAI宣布推出ChatGPT Plugins(插件集),赋予ChatGPT实时更新、…

chatGPT文章生成插件-用chatGPT写文章接入网站

chatGPT文章生成插件 ChatGPT是一种强大的自然语言生成技术,可以用于生成文章、文本摘要、对话生成、语言翻译等多种应用场景。在实际应用中,可以使用一些插件来实现ChatGPT的文章生成功能,以下是一些可能有用的插件介绍: AI Wri…

【CSS】实现梯形

简单说一下背景,就是需要实现一个展开收起的按钮。 那我第一个想到的方法,可不就是border自己画嘛。 1、border边框 width: 150px; border-top: 50px solid red; // 梯形的高 border-right: 50px solid transparent; // 往右延伸 border-bottom: 50px …

75-网络二(网络分层模型)

网络二二.网络分层模型1.网络协议(1)什么是网络协议(2)常见的协议2.OSI的7层模型与tcp/ip协议族体系4层结构(1)数据链路层(2)网络层(3)传输层(4)应用层3.为什么要分层?三.网络应用程序的通信流程网络一见:网络一 二.网络分层模型 1.网络协议 (1)什么是网络协议 网络协议就…

Python 小型项目大全 76~81

七十六、井字棋 原文:http://inventwithpython.com/bigbookpython/project76.html 井字棋是一种在3 3网格上玩的经典纸笔游戏。玩家轮流放置 X 或 O 标记,试图连续获得三个。大多数井字棋都以平局告终,但如果你的对手不小心,你也…

Three.js教程:顶点位置数据解析渲染

推荐:将NSDT场景编辑器加入你3D工具链其他工具系列:NSDT简石数字孪生顶点位置数据解析渲染 如果你没有WebGL基础,可以先不用记忆每个的threejs 具体内容,有一个大致印象即可,学习本节课的重点是建立顶点的概念。如果你…

Reactor设计模式

一、Reactor设计模式 1、什么是Reactor设计模式? Reactor模式是高性能I/O设计中,常用的设计模式。其中心思想是将所有要处理的I/O事件注册到一个中心I/O多路复用器上,同时主线程阻塞在多路复用器上,一旦有I/O事件到来或是准备就绪…

C++ 继承:概念定义、对象的赋值转换、继承作用域及派生类的默认成员函数

目录 一. 继承的概念和定义 1.1 继承的概念 1.2 继承的定义格式 1.3 继承关系和访问限定符 二. 基类和派生类对象的之间的赋值转换 三. 继承体系中的作用域 四. 派生类的默认成员函数 4.1 构造函数 4.2 拷贝构造函数 4.3 赋值运算符重载函数 4.4 析构函数 4.5 取地…

linux服务器禁止ping命令,linux服务器禁ping如何解除

linux服务器禁止ping命令,linux服务器禁ping如何解除 我是艾西,在我们搭建网站或做某些程序时,不少人会问禁ping是什么意思,怎么操作的对于业务有哪些好处等,今天艾西一次给你们说清楚。 禁PING的意思是:不…

相对全面的四足机器人驱动规划MATLAB和Simulink实现方式(足端摆线规划,Hopf-CPG,Kimura-CPG)

许久没更新四足机器人相关的博客文章,由于去年一整年都在干各种各样的~活,终于把硕士毕业论文给写好,才有点时间更新自己的所学和感悟。步态规划和足端规划只是为了在运动学层面获取四足机器人各关节的期望角位移和速度信号,再由底…

力扣---两数相加(c语言版)

🎈个人主页:🎈 :✨✨✨初阶牛✨✨✨ 🐻推荐专栏: 🍔🍟🌯 c语言初阶 🔑个人信条: 🌵知行合一 🍉本篇简介:>:记录一个力扣写了好久的一个问题 金句分享: ✨在心里种花,人…

uniapp 实现可滑动顶部选项卡(菜单)

利用和实现可滑动顶部选项卡,实现的切换效果类似下图这种(顶部tab下方swiper):(代码具体效果只是实现可滑动顶部选项卡的功能,具体样式可自定义修改) 一、分步骤展示 构建顶部tab选项按钮步骤…

00后卷王的自述,我难道真的很卷?

前言 前段时间去面试了一个公司,成功拿到了offer,薪资也从12k涨到了18k,对于工作都还没两年的我来说,还是比较满意的,毕竟一些工作3、4年的可能还没我高。 我可能就是大家说的卷王,感觉自己年轻&#xff…

[论文阅读笔记22]Identity-Quantity Harmonic Multi-Object Tracking

这是一篇优化匹配策略的文章, 通过密度估计的辅助, 估计一个边界框内有多少目标, 从而恢复遮挡的轨迹. 发表在IEEE TIP 2022. 论文地址: https://ieeexplore.ieee.org/abstract/document/9725267/ 0. Abstract 通常的MOT算法在匹配阶段时, 都是通过线性指派问题求解, 即会计算…

最近骗子有点多

就这几天,也就是这几天,我听到身边有两个人的家里人因为某某事情被骗。第一个是我旁边的同事,说是家里的老人被骗了好十几万,说是有一个高收益的旅行团,交钱了就免费旅游,旅游也是真去了,而且每…

一文弄懂访问者模式

关于设计模式,我们得结合生活中的案例来学习;最近我在网上也看了不少文章,今天想跟大家分享一下关于访问者模式的一些知识,先来看一个简单的案例吧。 相信大家都去过医院,看完病,医生都会给我们开一个处方…

数据结构:算法的时间复杂度和空间复杂度

Hello各位老铁们!我们又见面了,大家最近有没有坚持学习和敲代码呢?在这里小编就要督促一下大家了,我们每一天都敲一两道题,这样子久而久之的坚持下去你就会发现你已经在不知不觉的过程中变成了一个大佬。敲代码使我们快…

unity蒙板测试例子——传送门

返回目录 Unity蒙板测试例子——传送门一、例子介绍 大家好,我是阿赵。 蒙板测试(Stencil Test)是渲染管线的合并输出环节里面的一种测试,和透明度测试或者深度测试一样,它实际上也是控制颜色值是否应该显示出来的一种…

natapp + nginx 实现内网穿透

环境是我本地的win10 第一步:下载nginx压缩包并解压(这个自行百度吧) 第二步: 修改nginx的配置文件: 在最下方添加: #testserver {listen 8081;#你要映射的端口server_name localhost; #使用本地IPlocation / {proxy_pass…