文件的顺序读写(三)

文件的顺序读写

前面我们学习了文件是如何打开和关闭,打开文件后我们应该要知道如何操作文件中的数据(输入或输出数据)。

对文件数据的读写可以分为顺序读写随机读写。顺序读写,即挨着顺序对文件中的数据进行输入或输出。

下面内容我将要介绍顺序读写:

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

怎么理解输入和输出呢?

在这里插入图片描述

字符输入输出函数fgetc、fputc

fputs 向文件输出一个字符

fputs

int fputc( int c, FILE *stream );

第一个参数代表:要输出的字符的ASCII码值

第二个参数代表:要操作的文件指针,输出的位置

例如:

int main()
{
	//打开文件
	FILE* pf = fopen("contact.txt", "w");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;//文件打开失败,失败返回
	}
	fputc('h', pf);
	fputc('a', pf);
	fputc('h', pf);
	fputc('a', pf);
	fclose(pf);
	pf = NULL;
	return 0;
}

文件contact.txt里存的是haha(它们都是以ASCII码值来存放)

通过上面的表格,可以知道,fputc函数适用于所有输出流

问题

所有输出流是什么意思?

在这里插入图片描述

把数据给流:让流来区分要放去文件,屏幕,还啥

流已经被操作系统包装好了,

当从语言运行程序时,默认会打开三个流:

标准输出流:stdout

标准输出流:stdout 这三个流 的类型都是FILE*

标准错误流:stderr

例如:

printf: 标准输出流:stdout(流向屏幕)

scanf:标准输出流:stdout(键盘)

例如:

int main()
{
	fputc('a', stdout);//屏幕输出a;
	return 0;
}

流是一个高度抽象的概念

在我看来

FILE* 就是流的概念,你看看stdout ,stdin,stderr都是FILE*类型的,打开一个文件时返回值也是通过FILE *类型来接收,

打开文件的时候,FILE*就是一个文件流,流向文件的,

fputs

函数的功能就是把一个字符串写到文本上

具体格式:

int fputs( const char *string, FILE *stream );
string : 想要输出的字符串
stream : FILE*类型的结构体指针 

在这里插入图片描述

fgets

这个函数的功能是从流中读取一个字符存放到一个字符指针中去,前提是字符指针指向的空间够大

char *fgets( char *string, int n, FILE *stream );
string : 数据存储位置
n :可读的最大字符数
stream :FILE结构的指针

在这里插入图片描述
其实fgets这个函数的参数n可读的最大字符数虽然是5,以为可以读5个字符,实际上只能读到n - 1个字符,也就是4个字符,并且末尾会补‘\0’保证有5个字符

来看看如果一次录20个会发生什么
在这里插入图片描述

fprintf fscanf

fprintf

int fprintf( FILE *stream, const char *format [, argument ]...);

第一个参数是文件流指针,你要把格式化的数据输出到指向文件里
第二个参数就是格式化数据例如:printf

int printf( const char *format [, argument]... );
//printf函数的声明

从上面可以看出,fprintf 与printf ,相比fprintf比printf多了一个参数,所以我们可以先按照printf的方式进行输入,
其实printf默认把格式化的数据流到屏幕上去
而fprintf则流向文件里
我们可以下一下代码证明一下
在这里插入图片描述

因为fprintf 与fscanf 分别适用于所有的输出流、所有的输入流

在这里插入图片描述
其实,fprintf函数的功能就是将“区域三”的数据,以“区域二”的格式输出到“区域一”。

fscanf

既然理解了fprintf 函数,那么fscanf也是差不多的

int fscanf( FILE *stream, const char *format [, argument ]... );

fscanf函数的第一个参数是读取数据的位置,后面的参数我们也可以类比scanf函数的参数:

int scanf( const char *format [,argument]... );

直接上代码好理解:

#include <stdio.h>
#include <string.h>
#include <errno.h>
struct S
{
	char name[20];
	char sex[5];
	int age;
};
int main()
{
	//打开文件
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;//文件打开失败,失败返回
	}
	//对文件进行格式化输入操作
	struct S tmp = { 0 };
	fscanf(pf, "%s %s %d", tmp.name, tmp.sex, &(tmp.age));
	printf("%s %s %d\n", tmp.name, tmp.sex, tmp.age);
	//将tmp中的内容打印出来,看是否读取成功
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}



在这里插入图片描述
在这里插入图片描述
把区域一 的内容以区域二的格式,存到区域三里

fread fwrite

1、fwrite

size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );

fwrite以二进制的形式输出数据
第一个参数 输出数据位置,第二个参数,输出数据的元素大小,第三个要输出多少个元素,第四个参数输出数据目标位置,
注意:如果输出时报错或者输出的个数小于待输出的个数就会返回一个小于count的数。
例如:把字符串输出文件里

int main()
{
	//打开文件
	FILE* pf = fopen("data.txt", "wb");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;//文件打开失败,失败返回
	}
	char arr[20] = "abcde";
	fwrite(arr, sizeof(arr[0]), 3, pf);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

文本内容:abc,因为以二进制的形式存放进去 字符a的ASCII值为 97整数,存进去的就是97 的二进制
然后文本解释存进去的二进制就是a,所以我们打开文本时就能看到abc

如果文本是以大小端存放进去,然后以每个字节每个字节解析二进制代码:

fread

既然理解了fwrite,那么fread也是一样的,
fread只是fwrite的反方向
如图:
在这里插入图片描述

现在我们就把刚刚把abc存到data.txt数据拿出来

int main()
{
	//打开文件
	FILE* pf = fopen("data.txt", "rb");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;//文件打开失败,失败返回
	}
	char arr[20] = { 0 };
	fread(arr, sizeof(arr[0]), 3, pf);
	printf("%s", arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

在这里插入图片描述
注意此时是以rb的形式开的

总结:
scanf:从标准输入流(键盘)读取格式化的数据

fscanf:从所有的输入流读取格式化的数据

sscanf:把一个字符串转换成一个格式化的数据

printf:把格式化的数据输出到标准输出(屏幕)上

fprintf:把格式化的数据输出到所有输出流(屏幕\文件0…)上

sprintf:把格式化的数据转换成对应的字符串!

struct s {
	int a ;
	int b;
	};

int main()
{
	//打开文件
	struct s s = { 100,100};
	FILE* pf = fopen("data.txt", "r");
	if (pf == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;//文件打开失败,失败返回
	}
	//fscanf(stdin,"%d %d",&s.a,&s.b);
	//fprintf(stdout, "%d %d", s.a, s.b);

	/*fwrite(&s, sizeof(struct s), 1, stdout);*/
	char arr[100] = { 0 };

	sprintf(arr, "%d%d", s.a, s.b);
	printf("%s", arr);//100100

	fclose(pf);
	pf = NULL;
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2023框框

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值