文章目录

  • 文件的顺序读写
  • 字符输入输出函数fgetc、fputc
  • 问题
  • fputs
  • fgets
  • fprintf fscanf
  • fprintf
  • fscanf
  • fread fwrite
  • 1、fwrite
  • fread


文件的顺序读写

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

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

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

功能

函数名

适用于

字符输入函数

fgetc

所有输入流

字符输出函数

fputc

所有输出流

文本行输入函数

fgets

所有输入流

文本行输出函数

fputs

所有输出流

格式化输入函数

fscanf

所有输入流

格式化输出函数

fprintf

所有输出流

二进制输入

fread

文件

二进制输出

fwrite

文件

怎么理解输入和输出呢?

文件不是顺序读取会出现premature EOF 文件的顺序读写_打开文件

字符输入输出函数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函数适用于所有输出流

问题

所有输出流是什么意思?

文件不是顺序读取会出现premature EOF 文件的顺序读写_打开文件_02

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

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

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

标准输出流: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*类型的结构体指针

文件不是顺序读取会出现premature EOF 文件的顺序读写_c语言_03

fgets

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

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

文件不是顺序读取会出现premature EOF 文件的顺序读写_打开文件_04


其实fgets这个函数的参数n可读的最大字符数虽然是5,以为可以读5个字符,实际上只能读到n - 1个字符,也就是4个字符,并且末尾会补‘\0’保证有5个字符来看看如果一次录20个会发生什么

文件不是顺序读取会出现premature EOF 文件的顺序读写_数据_05

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则流向文件里

我们可以下一下代码证明一下

文件不是顺序读取会出现premature EOF 文件的顺序读写_输出流_06

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

文件不是顺序读取会出现premature EOF 文件的顺序读写_输出流_07


其实,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;
}

文件不是顺序读取会出现premature EOF 文件的顺序读写_输出流_08


文件不是顺序读取会出现premature EOF 文件的顺序读写_数据_09


把区域一 的内容以区域二的格式,存到区域三里

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的反方向

如图:

文件不是顺序读取会出现premature EOF 文件的顺序读写_数据_10

现在我们就把刚刚把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;
}

文件不是顺序读取会出现premature EOF 文件的顺序读写_输出流_11


注意此时是以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;
}