文件操作(下)(想要了解如何操作文件,那么看这一片就足够了!)

        前言:在文件操作(上)中,我们讲到了基础的文件操作,包括文件的打开,文件的关闭,以及文件的基础读写,那么除了之前学习的读写之外,还有什么其他的方式对文件进行读写操作吗?


✨✨✨这里是秋刀鱼不做梦的BLOG

✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客

那么废话不多说,我们直接开始讲解,书接上回,我会从以下三个方面继续我们的讲解:

想看文件操作(上),点击------------------------------------------------------------------------------------------->文件操作(上)(想要了解如何操作文件,那么看这一片就足够了!)-CSDN博客

目录

1.读写文件的其他操作

        (1)fscanf函数

        (2)fprintf函数

        补充:

区分printf 、fprintf 、 sprintf函数  + 区分scanf 、fscanf 、sscanf函数

        (3)fwrite函数

        (4)fread函数

2.文件的随机读写

        (1)fseek函数

        (2)ftell函数

        (3)rewind函数

3.文件读取结束的判定

        (1)feof函数

        (2)ferror函数


1.读写文件的其他操作

对于文件操作还有以下的几个函数:

函数名功能适用性
fscanf()格式化输入函数所有输入流
fprintf()格式化输出函数所有输出流
fread()二进制输入文件
fwrite()二进制输出文件

让我们一个一个来分析:

        (1)fscanf函数

先看一下官网对其的解释:

该函数的第一个参数是一个文件指针,第二个参数format是格式字符串,用于指定要读取的数据的格式;第三个参数...是要读取的数据的地址,它的返回值为成功匹配和读取的数据项数量。

我们直接使用实例来加深对其的理解:

#include<stdio.h>
struct Student
{
	char name[20];
	int age;
};
int main()
{
	struct Student stu = { 0 }; 
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//使用fscanf函数格式化将文件中内容输出
	fscanf(pf, "%s %d", stu.name, &(stu.age));
	printf("%s %d", stu.name, stu.age);
	fclose(pf);
	pf = NULL;
	return 1;
}

这样我们就完成了数据的格式化输出。

        (2)fprintf函数

先看一下官网对其的解释:

该函数的第一个参数是文件指针,第二个参数format是格式字符串,用于指定要写入的数据的格式,第三个参数...是要写入的数据,fprintf函数会根据格式字符串的指定,将数据按指定格式写入到文件中,它的返回值为成功写入的字符数量。

我们直接使用实例来加深对其的理解:

#include<stdio.h>
struct Student
{
	char name[20];
	int age;
};
int main()
{
	struct Student stu = { "zhangsan",20};
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//使用fprintf函数格式化将内容写入文件
	fprintf(pf, "%s %d", stu.name, stu.age);
	fclose(pf);
	pf = NULL;
	return 1;
}

这样我们就完成了数据的格式化输入。

        补充:

区分printf 、fprintf 、 sprintf函数  + 区分scanf 、fscanf 、sscanf函数

让我们先来看printf 、fprintf 、 sprintf这一组,先看一下这几个函数的定义:

printf函数:

fprintf函数:

sprintf函数:

根据之前所学习的fprintf函数的几个参数,我们可以知道:

printf:将数据格式化的输出在标准输出流;

fprintf:将数据格式化的输出在任意指定的输出流中;

sprintf:将数据格式化转换为字符串

这里就不在对printf和fprintf函数进行解释了(上文中已解释),只对sprintf函数进行解释:

我们直接使用案例讲解:

#include<stdio.h>
struct Student
{
	char name[10];
	int age;
};
int main()
{
	struct Student stu = { "zhangsan",20 };
	char str[20] = { 0 };
	//将stu结构体中的数据格式化转换为字符串后储存到str数组中
	sprintf(str, "%s %d", stu.name, stu.age);
	printf("%s", str);

	return 0;
}

从结果我们可以看出,sprintf函数将结构体中的数据格式化的转换成了字符串并储存到了str中。

区分完了printf 、fprintf 、 sprintf函数的区别,下面在让我们区分一下scanf 、fscanf 、sscanf这几个函数的区别,先看一下这几个函数的定义:

scanf函数:

fscanf函数:

sscanf函数:

根据之前所学习的fscanf函数的几个参数,我们可以知道:

scanf:将数据格式化的输出在标准输入流;

fscanf:将数据格式化的输出在任意指定的输出流;

sscanf:将字符串按照一定格式转换为格式化数据;

这里就不在对scanf和fscanf函数进行解释了(上文中已解释),只对sscanf函数进行解释:

我们直接使用案例讲解:

#include<stdio.h>
struct Student
{
	char name[10];
	int age;
};
int main()
{
	struct Student stu = { "zhangsan",20 };
	struct Student stu2 = { 0 };
	char str[20] = { 0 };
	//将stu结构体中的数据格式化转换为字符串后储存到str数组中
	sprintf(str, "%s %d", stu.name, stu.age);

	//将str中的数据格式化输出到stu2结构体中
	sscanf(str, "%s %d", stu2.name, &(stu2.age));
	printf("%s %d", stu2.name, stu2.age);
	return 0;
}

这样我们就完成了将字符数组中的字符串格式化输出了。

        在之前我们知道文件可分为文本文件和二进制文件,那么之前我们学习的都是将数据存储到文本文件中,那么如果我们想存储二进制数据,那该怎么办呢?接下来我们就讲解储存二进制数据的方法。

        (3)fwrite函数

先看一下官网对其的解释:

其中的各个参数分别为ptr是一个指向数据存储位置的指针;size是每个数据项的大小;count是要写入的数据项数量;stream是要写入的文件指针,该函数的返回值为实际写入的数据项数量。

现在我们直接使用实例让你更好的理解:

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr[5] = { 1,2,3,4,5 };
	//将arr中的数据以二进制的形式写入文件test.txt中
	fwrite(arr, sizeof(int), 5, pf);
	fclose(pf);
	pf = NULL;

	return 0;
}

注:由于是二进制写入,所以我们会看不懂其中的内容。实际上fwrite函数的作用就是将指定位置的数据写入到文件中。

        (4)fread函数

先看一下官网对其的解释:

其中的各个参数分别为ptr是一个指向数据存储位置的指针;size是每个数据项的大小;count是要读取的数据项数量;stream是要读取的文件指针,该函数的返回值为实际读取的数据项数量。

现在我们继续使用上面fread函数实例让你更好的理解:

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	int arr[5] = { 0 };
	//将文件test.txt中的二进制的数据读取到arr数组中
	fread(arr, sizeof(int), 5, pf);
	//打印读取到的数据
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}
	fclose(pf);
	pf = NULL;

	return 0;
}

注:由于是二进制读取,所以可以从文件中读取二进制数据,实际上fread函数的作用就是从文件中读取指定数量的数据项,存储到指定位置。

以上就是文件顺序读写的所有方法了!!!

2.文件的随机读写

了解了文件的顺序读写之后,那么我们就产生了一个问题——那么读写到文件的数据能不能不按照顺序呢?其实是可以的。

        这里我们就要讲解文件的随机读写的函数:

        大致为以下三个,分别为fseek、 ftell、 rewind:

        

        (1)fseek函数

fseek函数用于将文件指针定位到指定位置,它的声明如下:

其中的参数分别为stream是要定位的文件指针,offset是相对于origin的偏移量,origin是定位的起始位置,可以是以下值之一:

SEEK_SET:从文件开头开始计算偏移量;

SEEK_CUR:从当前位置开始计算偏移量;

SEEK_END:从文件末尾开始计算偏移量;

该函数的返回值为一个整数,返回0表示定位成功,返回非零值表示定位失败。

我们直接使用实例来讲解:

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//将文件指针从开头偏移6个单位
	fseek(pf, 6, SEEK_SET);
	//获取一个字符
	int ch = fgetc(pf);
	printf("%c", ch);
	fclose(pf);
	pf = NULL;

	return 0;
}

所以一句话总结fseek函数的作用就是移动文件指针的位置,使你能更灵活的读写文件。

        (2)ftell函数

ftell函数用于获取文件指针当前的位置。它的声明如下:

该函数的参数stream是要获取位置的文件指针,函数的返回值为当前文件指针的位置到开始位置的偏移量,以字节为单位,并且如果获取位置失败,ftell函数会返回-1。

我们直接使用实例来讲解:

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//将文件指针从开头偏移6个单位
	fseek(pf, 6, SEEK_SET);
	//打印偏移量
	int ret = ftell(pf);
	printf("%d", ret);
	fclose(pf);
	pf = NULL;

	return 0;
}

这样我们就了解了ftell函数的使用方式。

        (3)rewind函数

rewind函数用于将文件指针定位到开始位置。它的声明如下:

该函数的参数stream是要获取位置的文件指针,该函数就是将文件指针定位到开始位置,该函数无返回值。

我们直接使用实例来讲解:

#include<stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//将文件指针从开头偏移6个单位
	fseek(pf, 6, SEEK_SET);
	//打印偏移量
	int ret = ftell(pf);
	printf("%d\n", ret);

	//将文件指针定位到开始位置
	rewind(pf);
	ret = ftell(pf);
	printf("%d", ret);
	fclose(pf);
	pf = NULL;

	return 0;
}

这样我们就了解了rewind函数的使用方式。

3.文件读取结束的判定

我们知道使文件读取结束有两种可能:

        (1)文件在读取的过程中出现异常;

        (2)文件读取到了文件的末尾;

那么我们如何去判断文件读取结束时是因为出现异常而停止的还是因为读取到文件的末尾而停止的呢?

        这里我们要介绍两个函数:feof和ferror

        (1)feof函数

该函数的参数是要判断的文件的文件指针,当是由于读取到文件末尾而停止则返回非0整数,反之为0。

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

        (2)ferror函数

该函数的参数是要判断的文件的文件指针,当是由于读取到文件末尾而停止则返回非0整数,反之为0

ferror的作用是:当文件读取结束的时候,判断是读取结束的原因是否是:发生异常导致读取结束。

这里我们直接使用案例来加深理解:

#include <stdio.h>
int main()
{
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL) {
		perror("fopen");
		return 1;
	}
	//fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
	int ch = 0;
	while ((ch = fgetc(pf)) != EOF) 
	{
		printf("%c", ch);
	}
	//判断是什么原因结束的
	if (ferror(pf))
		printf("异常导致");
	else if (feof(pf))
		printf("读取结束导致");
	fclose(pf);
	pf = NULL;

	return 0;
}

这样我们就了解了feof和ferror函数的使用方法。

观看文件操作(上)---------------------------------------------------------------------------------------------------->文件操作(上)(想要了解如何操作文件,那么看这一片就足够了!)-CSDN博客


以上就是文件读取的所有内容了~~~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

P5725 【深基4.习8】求三角形

【深基4.习8】求三角形 - 洛谷https://www.luogu.com.cn/problem/P5725 import java.util.*;public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in); // 创建一个 Scanner 对象来读取用户输入int n sc.nextInt(); // 从用户输入中…

Linux根据时间删除文件或目录

《liunx根据时间删除文件》和 《Linux 根据时间删除文件或者目录》已经讲述了根据时间删除文件或目录的方法。 下面我做一些补充&#xff0c;讲述一个具体例子。以删除/home目录下的文件为例。 首先通过命令&#xff1a; ls -l --time-style"%Y-%m-%d %H:%M:%S"…

【数据结构与算法】快速排序(详解:快排的Hoare原版,挖坑法和双指针法|避免快排最坏时间复杂度的两种解决方案|小区间优化|非递归的快排)

引言 快速排序作为交换排序的一种&#xff0c;在排序界的影响力毋庸置疑&#xff0c;我们C语言中用的qsort&#xff0c;C中用的sort&#xff0c;底层的排序方式都是快速排序。相比于同为交换排序的冒泡&#xff0c;其效率和性能就要差的多了&#xff0c;本篇博客就是要重点介绍…

2024 ccfcsp认证打卡 2023 03 01 田地丈量

import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner in new Scanner(System.in);int n in.nextInt(); // 输入 n&#xff0c;表示矩形的数量int a in.nextInt(); // 输入 a&#xff0c;表示整个区域的长度int b in.nextInt()…

3.28学习总结

java 封装 封装体现了java的面向对象的特点,用户不用知道程序是如何运行的,只用按照所给的格式输入参数,便可得到对应的结果. 一个完整的封装需要每个实例变量都用private来修饰并拥有相应的public getter和setter方法. 代码 public class girl {private int age;public st…

C++:转义符(10)

在c中有一些字符无法被显示出来&#xff0c;所以需要使用些特殊字符加字母来展示 可以看到基本都是一个\加一个字母去只执行对应的一个效果 这里我选择几个对于当前来说比较重要的&#xff1a;\n &#xff0c;\\ &#xff0c;\t \n换行符 可以看到在c语言中他就是一个可以换行…

c++ 有名对象和匿名对象

c 有名对象和匿名对象 有名对象就是有名字的对象&#xff0c;匿名对象就是没有名字的对象。 #define _CRT_SECURE_NO_WARNINGS 1 using namespace std; #include<iostream> class score { public:score(){math 100;chinese 100;english 100;}score(int _math, int _…

GitHub开源项目权限管理-使用账号和个人令牌访问

1.打开后台账号设置 2.找到左下角的Developer settings 3.找到Personal access tokens 的 Tokens(classic) 4.选择创建新证书 5.填写证书信息 6.点击生成证书&#xff0c;复制证书并且保存起来&#xff08;血泪教训&#xff0c;证书只会在创建时显示一次&#xff0c;以后就再也…

<QT基础(5)>事件监听

事件监听 事件监听&#xff08;Event Handling&#xff09;是在程序中监视和响应发生的事件的一种机制。在Qt中&#xff0c;事件监听是一种常见的用于处理用户输入、系统事件以及其他类型事件的方法。通过事件监听&#xff0c;您可以在发生特定事件时捕获事件并执行相应的操作…

Ainx的多路由模式

&#x1f4d5;作者简介&#xff1a; 过去日记&#xff0c;致力于Java、GoLang,Rust等多种编程语言&#xff0c;热爱技术&#xff0c;喜欢游戏的博主。 &#x1f4d7;本文收录于Ainx系列&#xff0c;大家有兴趣的可以看一看 &#x1f4d8;相关专栏Rust初阶教程、go语言基础系列…

使用Zabbix监控NAS目录状态

在企业的数据存储和共享中,网络附加存储(NAS)扮演着至关重要的角色。为了确保NAS设备的稳定运行和数据的完整性,对其进行实时监控是必不可少的。Zabbix作为一款开源的网络监控解决方案,能够帮助我们实现这一目标。本文将介绍如何使用Zabbix监控NAS目录状态,以确保及时发现…

如何在CentOS使用Docker搭建MinIO容器并实现无公网ip远程访问本地服务

文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远程访问MinIO管理界面6. 固定MinIO公网地址 前言 MinIO是一个开源的对象存储服务器&#xff0c;可以在各种环境中运行&#xff0c;例如本地、Docker容器、Kubernetes集群等。它兼…

MySQL数据库 - 复杂查询(一)

一个不知名大学生&#xff0c;江湖人称菜狗 original author: Jacky Li Email : 3435673055qq.com Time of completion&#xff1a;2024.03.27 Last edited: 2024.03.27 目录 MySQL数据库 - 复杂查询&#xff08;一&#xff09; 第1关&#xff1a;交换工资 任务描述 相关知…

电平输入检测-定时器输入捕获

目录 一&#xff0c;引入 二&#xff0c;具体结构 三&#xff0c;实现步骤 四&#xff0c;PWM输入模式 一&#xff0c;引入 上篇博客&#xff0c;我们对于定时器的计数核心——时基单元作了细致的了解。这篇博文&#xff0c;我们来介绍定时器的四大功能模块之一——输入捕获…

Python基本运算

1.逻辑运算符 第四行会有黄色的下划线是因为这个不是系统推荐的写法&#xff0c;系统推荐的是第五行的链式比较&#xff1b; 2.短路求值 对于and而言&#xff0c;左边的语句是false&#xff0c;那么整体一定是false,右边的表达式就不会进行计算&#xff1b; 对于or而言&…

ChatGLM3:AttributeError_ can‘t set attribute ‘eos_token‘

最近在微调 ChatGLM3-6b 时&#xff0c;训练好模型之后&#xff0c;调用inference_hf.py函数验证模型的时候报了如下错误&#xff0c;下面是解决方案。 我在训练时使用的是ptuning_v2.yaml配置文件&#xff0c;训练运行代码如下&#xff1a; CUDA_VISIBLE_DEVICES1 python fi…

C++取经之路(其二)——含数重载,引用。

含数重载: 函数重载是指&#xff1a;在c中&#xff0c;在同一作用域&#xff0c;函数名相同&#xff0c;形参列表不相同(参数个数&#xff0c;或类型&#xff0c;或顺序)不同&#xff0c;C语言不支持。 举几个例子&#xff1a; 1.参数类型不同 int Add(int left, int right)…

智慧酒店(一):EasyCVR酒店安防视频监控系统的搭建与特点分析

一、行业背景 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经渗透到我们生活的方方面面&#xff0c;智慧酒店作为现代酒店业的重要发展方向&#xff0c;人工智能的应用显得尤为重要。数据显示&#xff0c;全国智慧酒店每年以10%—15%的速度快速增长&a…

大型DMP系统

前言 大家好&#xff0c;我是jiantaoyab&#xff0c;这是我作为学习笔记总结应用篇第一篇&#xff0c;本章大量的参考了别的博主的文章。 我们今天就先从搭建一个大型的 DMP 系统开始&#xff0c;利用组成原理里面学到的存储器知识&#xff0c;来做选型判断&#xff0c;从而更…

Redis高级面试题-2024

说说你对Redis的理解 Redis是一个基于Key-Value存储结构的开源内存数据库&#xff0c;也是一种NoSQL数据库。 它支持多种数据类型&#xff0c;包括String、Map、Set、ZSet和List&#xff0c;以满足不同应用场景的需求。 Redis以内存存储和优化的数据结构为基础&#xff0c;提…