C语言之文件操作篇(2)

news2024/11/23 7:33:53

目录

文件状态指针

文件流

文件的顺序读写

 fgetc

fputc

fgets

fputs

fscanf

fprintf

fread

fwrite


今天接下来我们讲解文件读写函数。🆗🆗🆗

文件状态指针

  • 文件状态指针也就是文件指示器。(可以理解为光标) 
  •  文件在不断被操作读取的过程中,文件状态指针是一直在移动的。

文件流

  • 流是怎样一个概念呢?我们简单通俗的介绍下。本篇我们把所有输入输出流分为两个标准输入出流文件流

流是一个高度抽象的概念!!在我们写程序的时候,我们需要将数据传到屏幕,存在硬盘上,传到网络上,U盘光盘等外部设备。不同的外部设备的读写方式不同,传输方式也不同。 有人觉得程序员也太难了,于是抽象化了流的概念。我们先将数据统一传输到流里面(文件流等),然后再传输到各个外部设备。

 

我们在写文件的时候,需要打开文件,关闭文件。我们用scanf从键盘上读取数据,printf向屏幕上打印数据,直接操作了为什么没有打开标准输入输出流呢? 

那是因为C语言程序运行起来,就默认打开了3个流。

  • stdin : 标准输入流(键盘)
  • stdout : 标准输出流(屏幕)
  • stderr : 标准错误流
  • 特别提醒:所有的流都是FILE*的指针类型

用打开标准输出流的方式打印26个字母

#include<stdio.h>
int main()
{
	char ch = 0;
	for (ch = 'a'; ch <= 'z'; ch++)
	{
		if (ch % 5 == 0)
			fputc('\n', stdout);//标准输出流
		fputc(ch, stdout);
	}
	//a-97
	//b-98
	//c-99
	//100换行了
	return 0;
}

 

用打开文件流的方式打印26个字母。------>下面fputc

#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char ch = 0;
	for (ch = 'a'; ch <= 'z'; ch++)
	{
		if (ch % 5 == 0)
			fputc('\n', pf);//文件流
		fputc(ch, pf);
	}
	//a-97
	//b-98
	//c-99
	//100换行了
	fclose(pf);
	pf = NULL;
	return 0;
}

文件的顺序读写

记住:站在内存数据的角度去理解!! 其次文件要用输入输出函数去输入输出操作,别手动键盘修改文本文件,这样达到不到想要的效果哦!!

功能                 函数名        适用于

字符输入函数          fgetc         所有输入流
字符输出函数          fputc         所有输出流
文本行输入函数        fgets         所有输入流
文本行输出函数        fputs         所有输出流
格式化输入函数        fscanf        所有输入流
格式化输出函数        fprintf       所有输出流
二进制输入            fread         文件
二进制输出            fwrite        文件

 

 

我们接下来详细的介绍以上各个函数。函数头文件 参数 返回值 使用去介绍


 fgetc

 fgetc - C++ Reference (cplusplus.com)

 

  • fgetc是以读的形式字符输出文件,内存读取数据。
  • 头文件 #include<stdio.h>
  • 参数FILE *stream 文件指针类型的指针变量 指向了一个文件信息区
  • 返回值是int类型(字符发生了整型提升)
  1. 成功后,将返回字符读取(提升为 int 值)ASCII码。
  2. 返回类型为 int 以适应特殊值 EOF,该值表示失败-1
  3. 如果位置指示器位于文件末尾,则该函数返回 EOF 并设置的 eof 指示器 (feof)。
  4. 如果发生其他读取错误,该函数还会返回 EOF,但改为设置其错误指示器 (ferror)。
#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int ch=fgetc(pf);
	printf("%c", ch);

	ch=fgetc(pf);
	printf("%c", ch);

	ch=fgetc(pf);
	printf("%c", ch);

	ch=fgetc(pf);
	printf("%c", ch);

	ch=fclose(pf);
	pf = NULL;
	return 0;
}

fputc

fputc - C++ Reference (cplusplus.com)

  

  • fputc以写的形式输入字符到文件中。
  •  头文件#include<stdio.h>
  • 参数int character 是整型 也就是字符整型提升 直接写字符即可
  • 参数FILE*stream 是文件指针类型的指针变量 指向了一个文件信息区
  • 返回值
  1. 成功后,将返回所写字符(整型提升)
  2. 如果发生写入错误,则返回 EOF 并设置错误指示器(ferror)。
#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputc('a', pf);//文件流
	fputc('b', pf);
	fputc('c', pf);
	fputc('d', pf);

	fclose(pf);
	pf = NULL;
	return 0;
}

 

请在文件中输入26个英文字母。 

#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char ch = 0;
	for (ch='a'; ch <= 'z'; ch++)
	fputc(ch, pf);
	fclose(pf);
	pf = NULL;
	return 0;
}
//换行
#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char ch = 0;
	for (ch = 'a'; ch <= 'z'; ch++)
	{
		if (ch % 5 == 0)
			fputc('\n', pf);//文件流
		fputc(ch, pf);
	}
	//a-97
	//b-98
	//c-99
	//100换行了
	fclose(pf);
	pf = NULL;
	return 0;
}

 


fgets

 fgets - C++ Reference (cplusplus.com)

 

从流中获取字符串

中读取字符并将其作为 C 字符串存储到 str 中,直到读取 num-1 个字符或到达换行符或文件末尾,以先发生者为准。
换行符使 fgets 停止读取,但它被函数视为有效字符,并包含在复制到 str 的字符串中。
终止空字符会自动附加到复制到 str 的字符之后

 

  • fgets是从文本文件stream读取输出字符串num str的函数 
  • 头文件#include<stdio.h>
  • 参数str是字符指针,指向一个字符数组的指针
  • 参数FILE*stream 是文件指针类型的指针变量 指向了一个文件信息区
  • 参数num是要复制到 str 的最大字符数(包括终止空字符)(整型提升)
  • 返回值是char*类型
  1. 成功后,函数返回 str
  2. 如果在尝试读取字符时遇到文件末尾,则设置 eof 指示器 (feof)。
  3. 如果在读取任何字符之前发生这种情况,则返回的指针为空指针(str 的内容保持不变)。
  4. 如果发生读取错误,则设置错误指示器(ferror),并返回空指针(但str指向的内容可能已更改)。
  •  读取停止情况
  1. 读取到了num-1个字符
  2. 到达换行符\n
  3. 到达文件末尾

只会读num-1个字符 

#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	char str[10] = { 0 };
	int ret=fgets(str,7,pf);//实际上只会读6个字符
	if (ret == EOF)
	{
		perror("fgets");
	}
	else
	printf("%s", str);
	fclose(pf);
	pf = NULL;
	return 0;
}

 

读到\n停止不读了 

#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	char str[100] = { 0 };
	int ret=fgets(str,12,pf);//实际上只会读6个字符
	if (ret == EOF)
	{
		perror("fgets");
	}
	else
	printf("%s", str);
	fclose(pf);
	pf = NULL;
	return 0;
}

 

fputs

fputs - C++ Reference (cplusplus.com)  

  • fputs是将str里的字符输出到文本文件stream 
  • 头文件#include<stdio.h>
  • 参数FILE*stream 是文件指针类型的指针变量 指向了一个文件信息区
  • 参数str 是字符指针 指向存放字符串的数组(由const修饰,防止被修改)
  • 返回值是int类型
  1. 成功时,将返回非负值。
  2. 出错时,该函数返回 EOF 并设置错误指示器(ferror)
#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char str[] = "abcdef";
	fputs(str,pf);
	fputs("abcdef", pf);
//两种写法
	fclose(pf);
	pf = NULL;
	return 0;
}

 


下面两个函数用结构体去举例子 fscanf是输入 fpirntf是输出,先看下对比。

你发现了什么?? 

  • scanf------->键盘-------->读取到程序中   fscanf-------->文件-------->读取到程序中 
  • printf-------->程序中的数据-------->输入到屏幕上   fprintf-------->程序中的数据------>输入到文件

fscanf

fscanf - C++ Reference (cplusplus.com)

 

  • fscanf是从文件读取数据
  • 头文件#include<stdio.h>
  • 参数FILE*stream 是文件指针类型的指针变量 指向了一个文件信息区
  • 其他和scanf是一样的,不用关心
  • 返回值是int类型
#include<stdio.h>
struct S
{
	char c;
	int i;
	float a;
};
int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//输入
	//struct S s = { 't',7,3.14 };
	//fprintf(pf,"%c  %d  %f",s.c,s.i,s.a);
	//格式必须一摸一样
	//输出
	struct S s = {0};
	fscanf(pf, "%c %d %f", &(s.c), &(s.i), &(s.a));
	printf("%c %d %f", s.c, s.i, s.a);

	fclose(pf);
	pf = NULL;
	return 0;
}

 

fprintf

fprintf - C++ Reference (cplusplus.com) 

 

  • fprintf是输入数据到文本文件
  • 头文件#include<stdio.h>
  • 参数FILE*stream 是文件指针类型的指针变量 指向了一个文件信息区
  • 其他和printf是一样的,不用关心
  • 返回值是int类型
  1. 成功后,将返回写入的字符总数。
  2. 如果发生写入错误,则设置错误指示器(ferror)并返回负数。
  3. 如果在写入宽字符时发生多字节字符编码错误,errno 将设置为 EILSEQ 并返回负数。
#include<stdio.h>
struct S
{
	char c;
	int i;
	float a;
};
int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	struct S s = { 't',7,3.14 };
	fprintf(pf,"%c  %d  %f",s.c,s.i,s.a);

	fclose(pf);
	pf = NULL;
	return 0;
}

 


前面的函数都是针对于文本文件的,下面这组函数针对的是二进制文件。 

fread

 fread - C++ Reference (cplusplus.com)

 

从流中读取数据块

中读取计数元素数组,每个元素的大小为字节并将它们存储在 ptr 指定的内存块中。
流的位置指示器按读取的总字节数前进。
如果成功,则读取的总字节数为(大小*计数)。

 

  • fread是向二进制文件读取数据
  • 头文件#include<stdio.h>
  • 参数FILE*stream 是文件指针类型的指针变量 指向了一个文件信息区
  • size_t size是每个元素的大小(以字节为单位)
  • size_t count是数组元素的个数
  • 参数void *ptr指向大小至少为 (size*count) 字节的内存块的指针(const修饰防止修改,void*类型的指针是因为不知道读取的是哪种类型的指针,void*不能被解引用操作,可以强制转换)
  • 返回值是size_t类型
  1. 返回成功读取的元素总数。
  2. 如果此数字与 count 参数不同,则表示读取时发生读取错误或到达文件末尾。在这两种情况下,都会设置正确的指标,可以分别用 ferror 和 feof 进行检查。
  3. 如果大小计数为零,则该函数返回零,并且流状态和 ptr 指向的内容保持不变。
    size_t 是无符号整数类型。
#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr[20] = { 0};//10个整型40个字节
	fread(arr, 4, 10, pf);
	int i = 0;
	for (i = 0; i < 10;i++)
	{
		printf("%d ", arr[i]);
	}
	fclose(pf);
	pf = NULL;
	return 0;
}

 

fwrite

fwrite - C++ Reference (cplusplus.com) 

 

写入要流式传输的数据块

计数元素数组(每个元素的大小为字节从 ptr 指向的内存块写入中的当前位置。
流的位置指示器按写入的总字节数前进。
在内部,该函数解释所指向的块,就好像它是一个类型的元素数组,并按顺序写入它们,就好像为每个字节调用一样。

  • fwrite是向二进制文件写输入数据的
  • 头文件#include<stdio.h>
  • 参数FILE*stream 是文件指针类型的指针变量 指向了一个文件信息区
  • 参数void *ptr是指向写入元素数组的的指针变量(const修饰防止修改,void*类型的指针是因为不知道输入的输入是哪种类型的指针,void*不能被解引用操作,可以强制转换)
  • size_t size是每个元素的大小(以字节为单位)
  • size_t count是数组元素的个数
  • 返回值size_t类型
  1. 返回成功写入的元素总数。
  2. 如果此数字与 count 参数不同,则写入错误阻止函数完成。在这种情况下,将为设置错误指示器(ferror)。
  3. 如果大小计数为零,则该函数返回零,错误指示器保持不变。
    size_t 是无符号整数类型。
#include<stdio.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };//10个整型40个字节
	fwrite(arr, 4, 10, pf);

	fclose(pf);
	pf = NULL;
	return 0;
}

 

文件的随机读写

文件结束的判定

✔✔✔✔✔最后,感谢大家的阅读,若有错误和不足,欢迎指正!

希望大家继续坚持在每天敲代码的路上。其实,没有人会一直带着你往前走,你自己一定要成为自己的救赎。

代码---------→【唐棣棣 (TSQXG) - Gitee.com】

联系---------→【邮箱:2784139418@qq.com】

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

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

相关文章

【U-Boot笔记整理】U-Boot 完全分析与移植

1. 大纲 大概内容如下&#xff1a; u-boot功能概述 目的功能细分 u-boot源码结构u-boot的配置、编译、连接过程 Makefile深入练习分析u-boot的Makefileu-boot可执行程序的组成 u-boot源码分析 SPL与第1阶段第2阶段核心&#xff1a;命令让u-boot的使用更加便利&#xff1a;env…

python图像检索系统设计与实现 计算机竞赛

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python图像检索系统设计与实现 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&#xff0c…

拼多多历史价格数据接口,拼多多商品历史价格接口,拼多多API接口

采集拼多多商品历史价格接口可以采用以下方式&#xff1a; 使用价格监控工具。价格监控工具是一种可以自动监测商品价格变化的工具&#xff0c;它可以帮助消费者快速采集拼多多商品价格信息&#xff0c;还可以提供价格变动趋势的图表分析&#xff0c;使消费者更好地掌握商品价…

Apache_Log4j2查找功能JNDI注入_CVE-2021-44228

Apache_Log4j2查找功能JNDI注入_CVE-2021-44228 文章目录 Apache_Log4j2查找功能JNDI注入_CVE-2021-442281 在线漏洞解读:2 环境搭建3 影响版本&#xff1a;4 漏洞复现4.1 访问页面4.2 poc漏洞验证 4.3 在dnslog获取个域名4.4 使用bp抓包进行分析4.5 通信成功&#xff0c;此处可…

【TA 挖坑04】薄膜干涉 镭射材质 matcap

镭射材质&#xff0c;相对物理的实现&#xff1f; 万物皆可镭射&#xff0c;个性吸睛的材质渲染技术 - 知乎 (zhihu.com) 薄膜干涉材质&#xff0c;matcap更trick的方法&#xff1f;matcapremap&#xff0c; MatCap原理介绍及应用 - 知乎 (zhihu.com) 庄懂的某节课也做了mat…

红队打靶:Nyx: 1打靶思路详解(vulnhub)

目录 写在开头 第一步&#xff1a;主机发现和端口扫描 第二步&#xff1a;ssh私钥登录获取初始立足点 第三步&#xff1a;sudo gcc提权 番外篇&#xff1a;如何掉进web渗透的陷阱无法自拔 总结与思考 写在开头 我个人的打靶顺序是根据红队笔记大佬的视频顺序&#xff0…

最新最全Jmeter+InfluxDB1.8+Grafana可视化性能监控平台搭建(win11本地)

本文前置条件&#xff1a; 1.Jmeter自行部署好&#xff0c;且版本最好要5.4以上&#xff1b; 2.目前InfluxDB最新是V2版本&#xff0c;但与Grafana兼容不太好&#xff0c;且和V1版本的配置连接不一样&#xff0c;本文是InfluxDB1.8版本&#xff1b; 3.介绍的是WIN11本地部署…

《PyTorch深度学习实践》第二讲 线性模型 课后练习

《PyTorch深度学习实践》第二讲 线性模型 课后练习 问题描述代码实现实现效果 问题描述 代码实现 import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D# 假设函数为 y 2x 1 x_data [1.0, 2.0, 3.0] y_data [3.0, 5.0, 7.0]# 定义…

【100天精通Python】Day70:Python可视化_绘制不同类型的雷达图,示例+代码

目录 1. 基本雷达图 2. 多组数据的雷达图 3 交互式雷达地图 4 动态雷达图 0 雷达图概述 雷达图&#xff08;Radar Chart&#xff09;&#xff0c;也被称为蜘蛛图&#xff08;Spider Chart&#xff09;或星型图&#xff0c;是一种用于可视化多维数据的图表类型。雷达图通常由…

目标文件格式

目标文件里有什么 目标文件格式 目标文件就是源代码编译后但未进行链接的中间文件&#xff08;linux下的.o&#xff09;。 ELF文件&#xff1a;从广义上看&#xff0c;目标文件与可执行文件的格式其实几乎是一样的&#xff0c;可以将目标文件与可执行文件看成是一种类型的文…

【Vue面试题二十】、你有写过自定义指令吗?自定义指令的应用场景有哪些?

文章底部有个人公众号&#xff1a;热爱技术的小郑。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享&#xff1f; 踩过的坑没必要让别人在再踩&#xff0c;自己复盘也能加深记忆。利己利人、所谓双赢。 面试官&#xff1a;你有写过自定义指令吗&a…

相似性搜索:第 1 部分- kNN 和倒置文件索引

图片来源&#xff1a;维亚切斯拉夫叶菲莫夫 一、说明 SImilarity 搜索是一个问题&#xff0c;给定一个查询的目标是在所有数据库文档中找到与其最相似的文档。 在数据科学中&#xff0c;相似性搜索经常出现在NLP领域&#xff0c;搜索引擎或推荐系统中&#xff0c;其中需要检索最…

课题学习(七)----粘滑运动的动态算法

一、 粘滑运动的动态算法 在实际钻井过程中&#xff0c;钻柱会出现扭振和粘滑现象&#xff08;粘滑运动–B站视频连接&#xff09;&#xff0c;但并不总是呈现均匀旋转。如下图所示&#xff0c;提取一段地下数据时&#xff0c;转盘转速保持在100 r/min&#xff0c;钻头转速在0-…

Namomo Summer Camp 23 Day 1

Namomo Summer Camp 23 Day 1 - Virtual Judge B - Brexiting and Brentering AC代码: #include<bits/stdc.h> #define endl \n //#define int long long using namespace std; string s; void solve() {cin>>s;int x-1;for(int is.size()-1;i>0;i--){if(s[i…

YOLOv5训练自己的数据集(超详细)

YOLOv5训练自己的数据集整个过程主要包括&#xff1a;环境安装----制作数据集----模型训练----模型测试----模型推理 一、准备深度学习环境 本人的笔记本电脑系统是&#xff1a;Windows10 首先进入YOLOv5开源网址 &#xff0c;手动下载zip或是git clone 远程仓库&#xff0c;本…

【C++心愿便利店】No.8---C++之重识类和对象

文章目录 前言一、再谈构造函数二、static成员三、友元四、内部类五、匿名对象六、再次理解类和对象 前言 &#x1f467;个人主页&#xff1a;小沈YO. &#x1f61a;小编介绍&#xff1a;欢迎来到我的乱七八糟小星球&#x1f31d; &#x1f4cb;专栏&#xff1a;C 心愿便利店 &…

6、docker下mysql修改配置文件

1、查看mysql镜像 如果没有mysql镜像则下载 docker images |grep mysql 2、查看mysql容器 docker ps |grep mysql 如果没有显示mysql容器信息&#xff0c;则创建 3、创建容器 docker run -it --name mysql-test -e MYSQL_ROOT_PASSWORDroot -p 3306:3306 -d f9653 4、在…

AB实验--科学增长

涉及的内容&#xff1a; AB实验的前置知识 AB实验的架构 AB实验的创建 AB实验的分析 AB实验的展示 AB实验的监控 AB扩展---指标监控 AB扩展---指标异动 AB扩展---异动分析 AB实验参考书籍 1.什么是AB AB 测试&#xff08;也称为拆分测试&#xff09;是一种统计方法&a…

SiC外延片测试方案

外延材料是实现器件制造的关键&#xff0c;主要技术指标有外延层厚度、晶格布局&#xff0c;材料结构&#xff0c;形貌以及物理性质&#xff0c;表面粗糙度和掺杂浓度等。下面阐述SiC外延表面常见的测试手段&#xff1a; 1. 外延层厚度&#xff08;傅里叶变换红外FT-IR&#xf…

xray安装与bp组合使用-被动扫描

xray安装与bp组合使用-被动扫描 文章目录 xray安装与bp组合使用-被动扫描1 工具官方文档&#xff1a;2 xray官网3 工具使用4 使用指令说明5 此为设置被动扫描6 被动扫描-启动成功7 启动bp7.1 设置bp的上层代理7.2 添加上层代理7777 --》指向的是xray7.3 上层代理设置好后&#…