printf函数输出问题

1、printf函数的对象是谁

printf()功能就是输出一个字符串到屏幕上,屏幕对象有两个,分别是标准输出、标准出错,printf()其对象就是标准输出。

2、标准输出与标准出错有什么区别

标准输出是由缓冲区的,其内容是先放在缓冲区,再输出。

标准出错是没有缓冲区的,其内容是直接输出。

3、缓冲区(buffer)

缓冲区就是一块内存区, 它用在输入输出设备和CPU之间,用来缓存数据 。它使得低速的输入输出设备和高速的CPU能够协调工作 ,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。

4、缓冲区的类型

缓冲区 分为三种类型:全缓冲、行缓冲和不带缓冲。

1)全缓冲

在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。

2)行缓冲

在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。

这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据。

3)不带缓冲

也就是不进行缓冲,

标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来。

5、printf()的输出问题

初步了解了缓冲区的概念之后,我们就来接合相关的例子来分析一下我们使用printf的时候回遇到的输出问题

//例子1
int main(int argc,char** argv)
{
    printf("helloworld");
    printf("appletree");
    while(1);  

    return 0;
}

/*

执行结果:不会输出任何的内容,然后卡在死循环中。

分析:因为printf函数是一个行缓冲区函数,所以必须要在标准输出缓冲区中遇到'\n'就可以输出东西

*/

//例子2
int main(int argc,char** argv)
{
    printf("helloworld");
	printf("appletree\n");
	printf("nihao");
	while(1);

	return 0;
}


/*

执行结果:输出helloworld和appketree,但是nihao并没有输出。

分析:证明必须遇到\n才可以将\n之前的全部东西输出。

*/


//例子3:
int main(int argc,char *argv[])
{
	printf("helloworld");
	printf("appletree");

	return 0;
}

/*

执行结果:输出helloworldappletree

分析:程序退出时,会刷新标准输出缓冲区。

*/

//例子4:
int main(int argc,char *argv[])
{
	while(1)
	{
		printf("hello");
		usleep(100000);  //0.1s
	}

	return 0;
}

/*

执行结果:等到缓冲区满了(1024B),就会将缓冲区中所有的数据全部输出。

分析:标准输出的缓冲区满了,即使没有'\n',程序也没有退出,也是会全部输出的。

*/


//例子5:
int main(int argc,char *argv[])
{
	int x;
	printf("helloworld");
	printf("appletree");
	scanf("%d",&x);
	while(1);

	return 0;
}

/*

执行结果:输出helloworldappletree

分析:键盘输入的函数也会刷新printf的缓冲区。

*/

//例子6:主动刷新缓冲区   ---> fflush()  -->  man 3 fflush
//功能: 刷新一个流。
//fflush - flush a stream
#include <stdio.h>
int fflush(FILE *stream);
参数:
	stream: 文件指针    如果要刷新标准输出缓冲区,这里填stdout。
返回值:
	成功:0
	失败:-1

int main(int argc,char *argv[])
{
	printf("helloworld");
	printf("appletree");
	fflush(stdout);   //---> 主动刷新标准输出缓冲区
	while(1);

	return 0;
}

//例子7: 将printf的输出对象修改为标准出错,你想输出什么东西,就会马上输出。
//修改输出对象: fprintf()  --> man 3 fprintf
#include <stdio.h>

int fprintf(FILE *stream, const char *format, ...);
参数:
	stream: 输出对象的文件指针。  stderr
	format: 输出的内容。
返回值: 输出的字符个数
         return the number of characters printed

printf("hello");          --> 默认的对象是标准输出
fprintf(stdout,"hello");  --> 将hello放在标准输出的缓冲区中,等价于上面那句话。
fprintf(stderr,"hello");  --> 将hello直接存放在标准出错中,而标准出错没有缓冲区的,所以会直接输出。

int main(int argc,char *argv[])
{
	fprintf(stderr,"hello");
	//fprintf(stdout,"hello");  //等价于printf("hello")
	while(1);
	
	return 0;
}

6、总结

1)遇到' \n '会刷新缓冲区

2)遇到return也会刷新缓冲区

3)当缓冲区满1024 byte的时候也会刷新缓冲区

4)键盘输入的函数也会刷新缓冲区

5)主动刷新缓冲区(fllush函数)

6)把标准输出改为标准出错,可以直接刷到屏幕上不经过缓冲区

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值