fwrite、fread、fprintf、fsanf以及流的定位——标准IO——day3

今天主要讲一下这四个函数接口:fwrite、fread、fprintf、fsancf以及流的定位:ftell、rewind、fseek

函数接口

fwrite

fwrite:
	size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
	向流中写入nmemb个对象,每个对象size字节大小,在ptr指向的空间中
参数:
	ptr:存放数据空间的首地址
	size:每个数据对象的大小
	nmemb:数据对象的个数
	stream:文件流指针
返回值:
	成功返回写入对象的个数
	失败返回0
	读到文件末尾返回0 

例子:向file.txt文件中传入学生类型的结构体数据

#include

typedef struct student{		//定义结构体
	char name[20];
	char sex;
	int age;
	int score;
}stu_x;

int main(void)		//主函数
{
	stu_x a = {"tom",'m',19,70};		//输入数据
	stu_x b = {"zero",'f',20,100};
	stu_x c[3] = {
		{"jack",'m',18,95},
		{"john",'f',19,80},
		{"lucky",'m',20,65},
	};

	FILE *fp = NULL;

	fp = fopen("file.txt","w");		//以写的方式打开文件

	if(NULL == fp)
	{
		perror("fail to fopen!");
		return -1;
	}

	fwrite(&a,sizeof(stu_x),1,fp);
	fwrite(&b,sizeof(stu_x),1,fp);
	fwrite(c,sizeof(stu_x),3,fp);

	fclose(fp);

	return 0;
}

结果:
在这里插入图片描述
可以看出来,数据已经写入文件中,但是cat只能显示ASCII码文件,不能显示二进制文件。

fread

fread:
	size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
功能:
	从流中读取nmemb个对象,每个对象size个字节,存放到ptr指向的空间中
参数:
	ptr:存放读取内容空间首地址
	size:读取对象的大小
	nmemb:读取对象的个数
	stream:文件流指针 
返回值:
	成功返回读到对象个数
	失败返回0
	读到文件末尾返回0 

我们可以将刚刚写入进去的数据重新读取出来:

#include

typedef struct student		//fread读取数据的话,必须得要有数据的结构体
{
	char name[20];
	char sex;
	int age;
	int score;
}stu_t;

int ShowStuInfo(stu_t tmpstu)		//以这种方式输出
{
	printf("name  = %s\n",tmpstu.name);
	printf(" sex  = %c\n",tmpstu.sex);
	printf(" age  = %d\n",tmpstu.age);
	printf("score = %d\n",tmpstu.score);
}

int main(void)
{
	FILE *p = NULL;
	size_t ret;
	int i = 0;
	stu_t a;
	stu_t b[10];
	p = fopen("file.txt","r");

	if(NULL == p)
	{
		perror("fail to fopen");
		return -1;
	}
	
	fread(&a,sizeof(stu_t),1,p);	//取a的地址
	ShowStuInfo(a);
	ret = fread(b,sizeof(stu_t),10,p);	//取数组b的地址,ret可以看到文件中还有几组数据
	for(i = 0;i < ret;++i)
	{
		ShowStuInfo(b[i]);
	}

	fclose(p);

	return 0;
}

结果:
fwrite、fread、fprintf、fsanf以及流的定位——标准IO——day3_第1张图片
我们可以看到,再进行第二个fread时,我们写入的读取对象的个数是10,但是实际上只有4个,所以最后ret等于4。

fprintf

fprintf 
	int fprintf(FILE *stream, const char *format, ...);
功能:
	将格式化字符串输出到stream指向的流中

我的个人观点,认为这个实际上跟printf一样,只不过输入时需要加文件流指针,下面举一个例子:

#include

int main(void)
{
	FILE *p = NULL;
	int Num1 = 100;
	int Num2 = 200;

	p = fopen("file.txt","w");

	if(NULL == p)
	{
		perror("fail to fopen");
		return -1;
	}

	fprintf(p,"hello world!\n num1 = %d , num2 = %d\n",Num1,Num2);	//将值输入到文件中

	fclose(p);

	return 0;
}

结果为:
fwrite、fread、fprintf、fsanf以及流的定位——标准IO——day3_第2张图片

fscanf

fsancf 
	int fscanf(FILE *stream, const char *format, ...);
功能:
	从流中读取格式化的字符串

我们可以将文件中的数据进行提取出来。

第二部分就是流的定位

ftell

ftell
	long ftell(FILE *stream);
功能:
	获得流的偏移量
在进行第一次打开文件时,流的偏移量是0

rewind

rewind
	void rewind(FILE *stream);
功能:
	将流的偏移量重新设置到开头

fseek

fseek 
	int fseek(FILE *stream, long offset, int whence);
功能:
	设置流的偏移量
参数:
	stream:文件流指针
	offset:偏移量
	> 0 向后偏移
	< 0 向前偏移
whence:
	SEEK_SET    文件开头
	SEEK_CUR    文件当前位置
	SEEK_END    文件末尾

我们可以做一个简单的例子,方便于了解

#include

int main(void)
{
	FILE *src = NULL;
	src = fopen("file.txt","w");

	if(NULL == src)
	{
		perror("fail to fopen");
		return -1;
	}

	fseek(src,10,SEEK_SET);		//在文件开头位置向右偏移10
	fputc('a',src);

	fseek(src,-5,SEEK_CUR);		//在文件当前位置向左偏移5
	fputc('c',src);

	fseek(src,0,SEEK_SET);		//回到文件开头位置
	fputc('b',src);

	fclose(src);
	
	return 0;
}

结果:
fwrite、fread、fprintf、fsanf以及流的定位——标准IO——day3_第3张图片
以上就是今天的所以内容,下面进行一个实例,从终端输入一个单词,获得单词的含义。

#include
#include

int main(void)
{
	FILE *src = NULL;
	src = fopen("dict.txt","r");	
	char word[256] = {0};
	char tmpbuff[4096];
	char *ptmp = NULL;
	char *pret = NULL;

	printf("please input one word:");
	gets(word);
	if(NULL == src)
	{
		perror("fail to fopen");
		return -1;
	}

	while(1)		//进行死循环
	{
		pret = fgets(tmpbuff,sizeof(tmpbuff),src);		//在源文件中,每一行结尾都有\n,所以我们可以使用fgets获得每一行的首地址,让pret进行记录
														//tmpbuff是存放字符串空间首地址,读取4096个字节,要保证足够大

		if(NULL == pret)	//判断是否读到文件末尾
		{
			break;
		}

		ptmp = tmpbuff;		

		while(*ptmp != ' ' && *ptmp != '\0')	//截取单词
		{
			++ptmp;
		}

		*ptmp = '\0';		//将第一个空格的位置换成\0

		ptmp++;

		while(*ptmp == ' ')
		{
			++ptmp;
		}

		if(strcmp(word,tmpbuff) == 0)	//进行字符串判断,看是否与输入的字符串相等
		{
			printf("word = %s\n",word);	//输出单词
			printf("ptmp = %s",ptmp);	//输出含义,因为已经截断了,所以ptmp当前的首地址是含义的地址
			return 0;
		}
	}

	fclose(src);

	printf("Word does not exist!\n");
	return 0;
}

结果:
fwrite、fread、fprintf、fsanf以及流的定位——标准IO——day3_第4张图片

以上就是今天内容!

共同学习,共同成长!

你可能感兴趣的:(Linux,服务器,数据库)