linux系统编程--标准IO--fputs、fgets、fseek函数

3.读写函数:
读写函数:
三类读写函数:
一类:行缓存 遇到新行符(\n) 或写满缓存时,即调用系统调用函数
读:fgets, gets, printf, fprintf,sprintf
写:fputs, puts,scanf

一个字符的读写,是否是行缓存?也是行缓存
读:fgetc, getc, getchar
写:fputc, putc,putchar
二类:无缓存 只要用户调这个函数,就会将其内容写到内核中
三类:全缓存 只有写满缓存再调用系统调用函数

3.1 行缓存的读写函数fgets和fputs
int fputs(const char *s,FILE *stream);
第一个参数:缓存,即写什么内容
第二个参数:写到哪里去
若成功则返回非负值,若出错则为EOF(EOF为宏,等价为-1)。

char *fgets (char *s, int size, FILE *stream)
第一个参数:缓存,即读到哪里去
第二个参数:读多少个字节
第三个参数:从什么地方读
返回值若成功则为s(缓存的地址),若已处文件尾端或出错则为null

注意和文件IO进行区别,区别就是将文件IO的第一个参数,调到了最后,就成了标准IO的参数。

例子:

#include <stdio.h>
//#include <unistd.h>
//#include <fcntl.h>

int main(int argc,char *argv[])
{

	FILE *fp;
	char buf[]="hello zengzhi\n";
	fp=fopen("./a.c","w+");//w a +
	if(fp==NULL)
	{
		printf("open file a.c fail\n");
		return -1;

	}

	printf("cread file a.c  suceess\n");
	fputs(buf,fp);
	fclose(fp);
	return 0;
	
} 

运行结果:
在这里插入图片描述
关于fgets()函数的例子:

#include <stdio.h>

//#include <unistd.h>
//#include <fcntl.h>

int main(int argc,char *argv[])
{

	FILE *fp;
	char buf[]="hello zengzhi\n";
	char readbuf[128]={0};
	fp=fopen("./a.c","w+");//w a +
	if(fp==NULL)
	{
		printf("open file a.c fail\n");
		return -1;

	}

	printf("cread file a.c  suceess\n");
	fputs(buf,fp);
	//start read
	fgets(readbuf,128,fp);
	printf("readbuf:%s\n",readbuf);
	fclose(fp);
	return 0;
	
} 

运行结果:
在这里插入图片描述为什么会读不到数据?和文件IO中的读写指针同理,在库函数缓存里依然需要调整读写指针的位置。这就需要引入读写位置指针函数fseek().
用法和lseek 函数一样,记得用这个函数的时候不要遗漏参数。
int fseek (FILE *__stream, long int __off, int __whence)
功能:调整读写的位置指针;
第一个参数:要调整的文件的文件描述符;
第二个参数:偏移量,每一读写操作所需要移动的距离,单位是字节的数量,可正可负(向后移,向前移);
第三个参数:当前位置的基点,有三个标志,
SEEK_SET:当前位置为文件的开头,新位置为偏移量的大小;
SEEK_CUR:当前位置为文件指针的位置,新位置为当前位置加上偏移量。
SEEK_END:当前位置为文件的结尾,新位置为文件的大小加上偏移量的大小。函
数的

fseek() 参数与lseek是一样的但是返回值不一样
lseek的返回值是:当前文件的位置指针值;
fseek()的返回值是:成功返回0,失败返回-1

#include <stdio.h>

//#include <unistd.h>
//#include <fcntl.h>

int main(int argc,char *argv[])
{

	FILE *fp;
	char buf[]="hello zengzhi\n";
	char readbuf[128]={0};
	fp=fopen("./a.c","w+");//w a +
	if(fp==NULL)
	{
		printf("open file a.c fail\n");
		return -1;

	}

	printf("cread file a.c  suceess\n");
	fputs(buf,fp);
	//start read
	fseek(fp,0,SEEK_SET);
	fgets(readbuf,128,fp);
	printf("readbuf:%s",readbuf);
	fclose(fp);
	return 0;
	
} 

运行结果:
在这里插入图片描述同时可以用rewind()函数进行调整
rewind(FILE *fp) 用于设定流的文件位置指示为文件开始,该函数调用成功无返回值。
rewind()等价于(void) fseek(fp 0, SEEK_SET)。
ftell(FILE *fp)
用于取得当前的文件位置,调用成功则为当前文件位置指示,若出错则为-1;

#include <stdio.h>

//#include <unistd.h>
//#include <fcntl.h>

int main(int argc,char *argv[])
{

	FILE *fp;
	char buf[]="hello zengzhi\n";
	char readbuf[128]={0};
	fp=fopen("./a.c","w+");//w a +
	if(fp==NULL)
	{
		printf("open file a.c fail\n");
		return -1;

	}

	printf("cread file a.c  suceess\n");
	fputs(buf,fp);
	//start read
//	fseek(fp,0,SEEK_SET);
	rewind(fp);
	fgets(readbuf,128,fp);
	printf("readbuf:%s",readbuf);
	fclose(fp);
	return 0;
	
} 

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

来测试fputs是不是行缓存:先去掉/n,看是不是能从库缓存写入内核缓存:
在这里插入图片描述

#include <stdio.h>

//#include <unistd.h>
//#include <fcntl.h>

int main(int argc,char *argv[])
{

	FILE *fp;
	char buf[]="hello zengzhi\n";
	char readbuf[128]={0};
	fp=fopen("./a.c","w+");//w a +
	if(fp==NULL)
	{
		printf("open file a.c fail\n");
		return -1;

	}

	printf("cread file a.c  suceess\n");
	fputs(buf,fp);
	//start read
	fseek(fp,0,SEEK_SET);
	fgets(readbuf,128,fp);
	printf("readbuf:%s",readbuf);
	fclose(fp);
	return 0;
	
} 

运行结果:
在这里插入图片描述发现依然可以,为什么,这是因为在使用fclose()关闭文件时,会强制数据从库缓存写入内核缓存。

当在fclose()关闭文件前加入死循环,不让其进行关闭操作时,此时就不能写入。默认情况下是可以关闭的

#include <stdio.h>
//#include <unistd.h>
//#include <fcntl.h>

int main(int argc,char *argv[])
{

	FILE *fp;
	char buf[]="hello zengzhi";
	fp=fopen("./a.c","w+");//w a +
	if(fp==NULL)
	{
		printf("open file a.c fail\n");
		return -1;

	}

	printf("cread file a.c  suceess\n");
	fputs(buf,fp);
	while(1);
	fclose(fp);
	return 0;
	
} 

运行结果:
在这里插入图片描述3.2 刷新缓存函数:fflush(FILE *fp)
把库函数中的缓存的内容强制写到内核中。
例子:

#include <stdio.h>
//#include <unistd.h>
//#include <fcntl.h>

int main(int argc,char *argv[])
{

	FILE *fp;
	char buf[]="hello zengzhi";
	fp=fopen("./a.c","w+");//w a +
	if(fp==NULL)
	{
		printf("open file a.c fail\n");
		return -1;

	}

	printf("cread file a.c  suceess\n");
	fputs(buf,fp);
	fflush(fp);
	while(1);
	fclose(fp);
	return 0;
	
} 

运行结果:
在这里插入图片描述fclose()含有fflush()

3.3 无缓存:stderr

stuout 是行缓存,因为没有\n,所以不输出。

#include <stdio.h>

int main(int argc,char *argv[])
{
	printf("hello linux");//stdout
	while(1);
	return 0;



}

#include <stdio.h>

int main(int argc,char *argv[])
{
//	printf("hello linux");//stdout
	fputs("hello linux",stdout);
	while(1);
	return 0;



}

运行结果:
在这里插入图片描述`
加入\n可以显示,或者使用fflush()进行刷新。

#include <stdio.h>

int main(int argc,char *argv[])
{
//	printf("hello linux\n");//stdout
	fputs("hello linux",stdout);
	while(1);
	return 0;



}

#include <stdio.h>

int main(int argc,char *argv[])
{
//	printf("hello linux");//stdout
	fputs("hello linux",stdout);
	fflush(stdout);
	while(1);
	return 0;



}

而stderr为无缓存,可以直接显示

#include <stdio.h>

int main(int argc,char *argv[])
{
//	printf("hello linux");//stdout
	fputs("hello linux",stderr);
//	fflush(stdout)
	while(1);
	return 0;



}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值