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)把标准输出改为标准出错,可以直接刷到屏幕上不经过缓冲区