C语言 | 文件操作(下)【必收藏】

news2024/11/19 2:20:38

文件操作(下)

    • 5、文件的顺序读写
      • 5.1 顺序读写函数介绍
        • 5.1.1 fputc与fgetc
        • 5.1.2 fputs与fgets
        • 5.1.3 fprintf与fscanf
        • 5.1.4 fread与fwrite
      • 5.2 对比一组函数
    • 6. 文件的随机读写
      • 6.1 fseek
      • 6.2 ftell
      • 6.3 rewind
    • 7. 文件读取结束的判定
      • 7.1 被错误使用的feof
    • 8. 文件缓冲区

5、文件的顺序读写

5.1 顺序读写函数介绍

5.1.1 fputc与fgetc

请看:
文件操作(上)

5.1.2 fputs与fgets

fputs: 文本行输出函数

int fputs ( const char * str, FILE * stream );
//          字符串指针         文件指针

代码:

int main()
{
	//1.打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	
	//2.写文件
	fputs("I am a student.\n", pf);//\n换行
	fputs("are you ok???\n", pf);
	
	//3.关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

程序执行结果:文件中写入两行字符串,换行后有一个空行!
在这里插入图片描述
fgets:

char * fgets ( char * str, int num, FILE * stream );
//            字符串指针   读取的字符个数  文件指针

举例1:
往文件中放入以下内容
在这里插入图片描述
代码:

int main()
{
	//1.打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//2.读文件
	char arr[20] = "xxxxxxxxxxxxxxxxxxxx";
	fgets(arr, 5, pf);//要读5个字符
	printf("%s\n", arr);

	//3.关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

调试观察:
通过观察发现,我们要读取5个字符,但实际只读取了4个有效字符"abcd",末尾自动添加一个"\0",也就是只读取了n-1个字符
在这里插入图片描述

运行结果:打印"abcd"

在这里插入图片描述

举例2: 文本行输入函数
往文件中放入以下内容
在这里插入图片描述
代码:

int main()
{
	//1.打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//2.读文件
	char arr[20] = "xxxxxxxxxxxxxxxxxxxx";
	fgets(arr, 10, pf);//要读10个字符
	printf("%s\n", arr);

	//3.关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

调试观察:
可以观察到只读取了5个有效字符,还有一个"\n"和一个"\0",也就是说当遇到换行时,后标的字符都不会再读取,当然末尾是依旧要补"\0"的
在这里插入图片描述
运行结果:打印"abcde"
在这里插入图片描述

5.1.3 fprintf与fscanf

首先要明白一个概念
什么是可变参数列表?
例如:printf

//printf
int printf ( const char * format, ... );
//                                可变参数列表

举例:参数的数量是可变的

int main()
{
	printf("abcde\n");//一个参数
	printf("%d\n", 100);//两个参数
	printf("%d %c\n", 100, 'a');//三个参数
	return 0;
}

进入正题:

fprintf: 格式化输出函数

//fprintf
int fprintf ( FILE * stream, const char * format, ... );
//            文件指针                             可变参数列表

代码:

struct S
{
	char name[20];
	int age;
	float score;
};

int main()
{
	struct S s = { "xiaoming", 18, 99.0f };
	//1.打开文件
	FILE* pf = fopen("test.txt", "w");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//2.写文件
	fprintf(pf, "%s %d %.1f", s.name, s.age, s.score);//格式化的输出函数

	//3.关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:结构体中的内容被写到了文件中

在这里插入图片描述

fscanf: 格式化输入函数

int fscanf ( FILE * stream, const char * format, ... );//从文件中读

用上文中fprintf向文件中输出的结果为例
代码:

struct S
{
	char name[20];
	int age;
	float score;
};

int main()
{
	struct S s = { 0 };
	//1.打开文件
	FILE* pf = fopen("test.txt", "r");
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//2.读文件
	fscanf(pf, "%s %d %f", s.name, &(s.age), &(s.score));//格式化的输入函数

	//将读取的结果打印出来
	fprintf(stdout, "%s %d %.1f", s.name, s.age, s.score);

	//3.关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

程序执行结果:成功读取到了文件中的内容,并打印在了屏幕上

在这里插入图片描述

5.1.4 fread与fwrite

fwrite: 将ptr指向的空间中count个大小为size的数据写到文件中

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
//              ptr指向的空间      大小            个数         文件指针

代码:

struct S
{
	char name[20];
	int age;
	float score;
};

int main()
{
	struct S s = { "wangwu",18,66.6f };
	//1. 打开文件
	FILE* pf = fopen("test.txt", "wb");//二进制的写
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//2. 写文件
	fwrite(&s, sizeof(struct S), 1, pf);//将s所指向空间中大小为sizeof(struct S)的1个数据写到pf所指向的文件中

	//3. 关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:因为写入的是二进制的信息,所以人是看不懂的

在这里插入图片描述

fread: 从文件中读取count个大小为size的数据存放到ptr指向的空间中

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
//            ptr指向的空间     大小       个数         文件指针

代码:

//fread
struct S
{
	char name[20];
	int age;
	float score;
};

int main()
{
	struct S s = { 0 };
	//1. 打开文件
	FILE* pf = fopen("test.txt", "rb");//二进制的读
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	//2. 写文件
	fread(&s, sizeof(struct S), 1, pf);
	printf("%s %d %f", s.name, s.age, s.score);

	//3. 关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:
在这里插入图片描述

5.2 对比一组函数

scanf/printf: 针对标准输入流/标准输出流的 格式化 输入/输出函数
fscanf/fprintf: 针对所有输入流/所有输出流的 格式化 输入/输出函数
sscanf/sprintf:

  1. sprintf: 将格式化的数据写到字符串中,可以理解为将格式化的数据转换成字符串
int sprintf ( char * str, const char * format, ... );

代码举例:

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	struct S s = { "lisi",18,80.0f };
	char arr[20] = { 0 };
	sprintf(arr, "%s %d %f", s.name, s.age, s.score);//将结构体变量s中的内容转换成字符串
	printf("%s\n", arr);
	return 0;
}

执行结果:
在这里插入图片描述

  1. sscanf: 从字符串中提取格式化的数据,也可以理解为将字符串转换为格式化的数据
int sscanf ( const char * s, const char * format, ...);

代码举例:

struct S
{
	char name[20];
	int age;
	float score;
};
int main()
{
	char arr[100] = { 0 };
	struct S s = { "lisi",18,80.0f };
	
	//临时变量
	struct S tmp = {0};
	
	//将s中的各个数据转化成字符串,存放在arr中
	sprintf(arr, "%s %d %f", s.name, s.age, s.score);

	//从arr中提取格式化的数据存放在tmp中
	sscanf(arr, "%s %d %f", tmp.name, &(tmp.age), &(tmp.score));
	printf("%s %d %f", tmp.name, tmp.age, tmp.score);

	return 0;
}

执行结果:
在这里插入图片描述

6. 文件的随机读写

6.1 fseek

根据文件指针的位置和偏移量来定位文件指针(文件内容的光标)。

int fseek ( FILE * stream, long int offset,  int origin );

代码:

int main()
{
	FILE* pFile;
	pFile = fopen("test.txt", "wb");
	fputs("This is an apple.", pFile);
	fseek(pFile, 9, SEEK_SET);
	fputs(" sam", pFile);//This is a sample.
	fclose(pFile);
	pFile = NULL;
	return 0;
}

执行结果:
在这里插入图片描述

6.2 ftell

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

long int ftell  ( FILE * stream );

代码:

int main()
{
	FILE* pFile;
	long size;
	pFile = fopen("test.txt", "rb");
	if (pFile == NULL)
		perror("fopen");
	else
	{
		fseek(pFile, 0, SEEK_END); 
		size = ftell(pFile);
		fclose(pFile);
		printf("Size of test.txt: %ld bytes.\n", size);
	}
	return 0;
}

运行结果:
在这里插入图片描述

6.3 rewind

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

void rewind ( FILE * stream );

代码:

int main()
{
	int n;
	FILE* pFile;
	char buffer[27];
	pFile = fopen("myfile.txt", "w+");
	for (n = 'A'; n <= 'Z'; n++)
		fputc(n, pFile);
	rewind(pFile);
	fread(buffer, 1, 26, pFile);
	fclose(pFile);
	pFile = NULL;
	buffer[26] = '\0';
	printf(buffer);
	return 0;
}

7. 文件读取结束的判定

7.1 被错误使用的feof

牢记:在文件读取过程中,不能用feof函数的返回值直接来判断文件的是否结束。

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

  1. 文本文件读取是否结束,判断返回值是否为EOF( fgetc ),或者NULL( fgets )
    例如:
    • fgetc 判断是否为EOF .
    • fgets 判断返回值是否为NULL .

  2. 二进制文件的读取结束判断,判断返回值是否小于实际要读的个数。
    例如:
    • fread判断返回值是否小于实际要读的个数。

8. 文件缓冲区

ANSIC 标准采用“缓冲文件系统” 处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根据C编译系统决定的。

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

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

相关文章

Python爬虫实战:利用代理IP批量下载哔哩哔哩美女视频

文章 目录 1.前言2.爬取目标3.准备工作3.1 环境安装3.2 代理免费获取 四、爬虫实战分析4.1 翻页分析4.2 获取视频跳转链接4.3 下载视频4.4 视频音频合并4.5 完整源码 五、总结 1.前言 粉丝们&#xff08;lsp&#xff09;期待已久的Python批量下载哔哩哔哩美女视频教程它终于来…

Java中File文件和IO流

File文件和IO流 概述 FIle是java.io.下面的包&#xff0c;用于代表当前操作系统的文件 可以获文件信息&#xff0c;判断文件类型&#xff0c;创建删除文件夹 注意&#xff1a;File只能对文件本身进行操作&#xff0c;不能读写文件里面存储的数据 …

Docker三分钟部署ElasticSearch平替MeiliSearch轻量级搜索引擎

&#x1f469;&#x1f3fd;‍&#x1f4bb;个人主页&#xff1a;阿木木AEcru (更多精彩内容可进入主页观看) &#x1f525; 系列专栏&#xff1a;《Docker容器化部署系列》 《Java每日面筋》 &#x1f4b9;每一次技术突破&#xff0c;都是对自我能力的挑战和超越。 目录 一、 …

基于web的摩托车销售系统的设计与实现-计算机毕业设计源码031706

摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对摩托车销售系统等问题&#xff0c;对摩托车…

手把手教你使用kimi创建流程图【实践篇】

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 引言 在昨日的文章中&#xff0c;我们介绍了如何使用Kimi生成论文中的流程图。今天&#xff0c;我们将更进一步&#xff0c;通过实践案例来展示Kimi在生成流程图方面的应用。这不仅将加…

火绒被骂惨,良心居然也翻车?剩下3款软件还被误认为外国人开发

万万没想到&#xff0c;公认的国产良心软件“火绒”&#xff0c;居然也翻车&#xff0c;很多网友对其大失所望&#xff0c;甚至忍不住吐槽让他不要砸了自己的招牌。 事情的起因是这样的&#xff0c;火绒推出应用商店&#xff0c;并于正式公测&#xff0c;这是要逐渐走向全家桶的…

淘宝店铺商家订单API-接入ERP,多平台订单同步的利器

淘宝开放平台给商家们提供了丰富的API&#xff0c;以方便大家扩展业务流程。但是需要调用这些API&#xff0c;商家们要提交资质审核&#xff0c;审核条件也是很严格的。第三方数据公司的存在可以为大家解决这个问题。 custom-自定义API操作 请求参数 请求参数&#xff1a;ap…

联发科MT6775(Helio P70)_MTK6775处理器规格参数_处理器资料

联发科MT6775(Helio P70)采用了台积电12nm工艺制程八核处理器&#xff0c;由4颗 Arm Cortex-A73 2.1GHz 4颗Arm Cortex-A53 2.0GHz组成。其GPU为ARM Mali-G72 MP3&#xff0c;运行时高达900MHz&#xff0c;比上一代Helio P60效能提升了13%。 值得注意的是&#xff0c;联发科MT…

java打印金字塔paremid和空心金字塔

java打印金字塔 首先确定每行打印几个空格&#xff0c;在确定每行打印几个* 设总层数为layers&#xff0c;当前层数为i。 则每行打印空格数layers-i&#xff0c;每行打印星号数2*i-1 import java.util.Scanner;public class Paremid{public static void main(String[] args) …

搜索引擎的“道”

目录 1. 网页下载&#xff08;解决有没有的问题&#xff09; 1.1 遍历算法 1.1.1 广度优先搜索 1.1.2 深度优先搜索 1.2 网络爬虫 1.2.1 用BFS 还是DFS? 1.2.2 URL提取 1.2.3 哈希表存储URL下载记录 2. 索引构建&#xff08;解决快不快的问题&#xff09; 2.1 布尔…

AI作画Prompt不会写?Amazon Bedrock Claude3.5来帮忙

最新上线的Claude3.5 Sonnet按照官方介绍的数据来看&#xff0c;在多方面超越了CPT-4o&#xff0c;是迄今为止最智能的模型。 而跟上一个版本相比&#xff0c;速度是Claude 3 Opus的两倍&#xff0c;成本只有其五分之一。 Claude3.5 Sonnet不仅擅长解释图表、图形或者从不完…

AI赋能影视解说:Rap说唱玩法拆解!

在影视解说的领域&#xff0c;竞争一直非常激烈&#xff0c;众多创作者纷纷涌入这个热门的赛道。为了在众多声音中脱颖而出&#xff0c;创新成为了关键。最近&#xff0c;一种结合AI技术的解说方式——Rap说唱解说&#xff0c;以其新颖的形式和高效的创作过程&#xff0c;赢得了…

Linux学习第52天:Linux网络驱动实验(三):一往(网)情深

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 许久没有更新&#xff0c;的确是最近有点懈怠了。没有任何借口&#xff0c;接受所有的批评。接下来无论如何也要坚持下去&#xff0c;不管处于什么境地、什么原因&am…

vue3 Cesium 离线地图

1、vite-plugin-cesium 是一个专门为 Vite 构建工具定制的插件&#xff0c;用于在 Vite 项目中轻松使用 Cesium 库。它简化了在 Vite 项目中集成 Cesium 的过程。 npm i cesium vite-plugin-cesium vite -D 2、配置vite.config.js import cesium from vite-plugin-cesiumexp…

生产环境:CentOS 7 Docker 20.10.19离线部署(为离线部署k8s做准备)

背景描述&#xff1a;离线部署Docker环境 在现代IT基础设施中&#xff0c;Docker已经成为应用容器化的标准工具。它简化了应用程序的部署和管理&#xff0c;使开发者和运维工程师能够以更高的效率和一致性进行工作。然而&#xff0c;在某些场景下&#xff0c;由于安全性、网络…

WMS在发展过程中会遇到哪些挑战?

在仓库管理系统&#xff08;Warehouse Management System, WMS&#xff09;的发展过程中&#xff0c;会遇到以下一些挑战&#xff1a; 1、技术整合&#xff1a; 将WMS与现有的ERP&#xff08;企业资源计划&#xff09;、TMS&#xff08;运输管理系统&#xff09;等系统进行有效…

uniapp 小程序 堆叠轮播图 左滑 右滑 自动翻页 点击停止自动翻页

uniapp 小程序 堆叠轮播图 左滑 右滑 自动翻页 点击停止自动翻页 超过指定时间未点击滑动 则继续开始滚动 直接上代码 componentSwiper.vue 需要注意页面切换时清除计时器 <template><view><view class"swiperPanel" touchstart"startMove"…

1.Orange Zero2介绍及刷机启动

Orangepi Zero2 1.Orangepi Zero2简介2.刷机和系统启动 1.Orangepi Zero2简介 为什么学 学习目标依然是Linux系统&#xff0c;平台是ARM架构蜂巢快递柜&#xff0c;配送机器人&#xff0c;这些应用场景用C51,STM32单片机无法实现第三方介入库的局限性&#xff0c;比如刷脸支付…

C++ 教程 - 06 类的封装、继承、多态

文章目录 封装继承多态 封装 在private/protected 模块放置数据或者底层算法实现&#xff1b;在public块提供对外接口&#xff0c;实现相应的功能调用&#xff1b;类的封装案例 #include <iostream> using namespace std;// 类的定义 一般放在头文件 class Stu {public…

STM32中五个时钟源:HSI、HSE、LSI、LSE、PLL

时钟系统是处理器的核心&#xff0c;或者说时钟是单片机的心脏。 1.单片机内部需要储存器、累加器&#xff0c;这些都需要逻辑门电路。比如锁存器就是一个D触发器&#xff0c;而触发器的置1、清0、置数的功能都需要跳变沿。D触发器就是上升沿后存入数据&#xff0c;而这个上升…