前言:
近日,在进行一个“私有云”项目中,遇到了关于缓存输出的问题,不免想到每一个学C语言的人写的第一个程序“helloworld”。这个程序从初学者的角度来看,也就短短几行,非常简单,但再回首,这是一个不简单的程序,可以说不是每一个人都会写“helloworld”,更精确的说是写对。真正读懂“helloworld”是需要时间的累积的。
今天在这里主要介绍的是“helloworld”中的第六行printf("helloworld\r\n");
<pre name="code" class="html">#include <stdio.h>
int main(int argc,char **argv)
{
printf("helloworld\r\n");
return 0;
}
正文:
初学者可能会疏忽大意,将这句代码敲成“printf("helloworld\n");”或是“printf("helloworld\r");”或是“printf("helloworld");”,这三种不同的写法会有不
同的结果,感兴趣的初学者可以自行尝试一下,这里不再演示结果。
很多时候都会出现这样一个情况,无论什么语言,直接输出无法显示出来,从一定程度上这是因为是存在缓存中,这里将做一个系统的总结:
(1)printf \r \n
printf 确实有缓冲区的问题
别人的东西:printf会把东西送到缓冲区,而如果缓冲区不刷新到话,你便不会在屏幕上看到东西,而能导致缓冲区刷新到情况有这些:
1-- 强制刷新 fflush;
fflush用于清空缓冲流,虽然一般感觉不到,但是默认printf是缓冲输出的。fflush(stdout),使stdout清空,就会立刻输出所有在缓冲区的内容。 fflush(stdout)这个例子可能不太明显,但对stdin很明显。
例:
A
int a,c;
scanf("%d",&a);
c=getchar();
输入: 12(回车)
结果: a=12 ,c= '\n'
B
int a,c;
scanf("%d",&a);
fflush(stdin);
c=getchar();
输入: 12(回车)
结果:a=12, c暂时未得到输入值
再输入c,因为getchar也是缓冲输入,'\n'本还在缓冲区,但是被清空了。
fflush不能作用于重定向输入流。
fflush(stdin)刷新标准输入缓冲区,把输入缓冲区里的东西丢弃
fflush(stdout)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上
fflush()的作用是:如果圆括号里是已写打开的文件的指针,则将输出缓冲区的内容写入该指针指向的文件,否则清除输出缓冲区。
stdout是系统定义的标准输出文件指针,默认情况下指屏幕,那就是把缓冲区的内容写到屏幕上。可是从代码中看不出缓冲区会有什么内容,所以它实际上没有起什么作用。
2--放到缓冲区到内容中包含\r \n ;
\r转义是回车= 光标到达最左侧(行首)(类似于控制屏幕或者从键盘的Enter键输入)
\n是换行=移到下一行(控制“打印机”)
只回车——打印的东西会覆盖同行以前的内容;只换行——打印的东西会在下一行的先一个位置继续。
.\r实际是回到行首。\n如果下一行已经有了一些内容的话它会在那些内容的后边.因为一般情况下下一行是没有数据的,很多时候\n也就成了\r\n作用一样。
这么看上去确实似乎有“对缓冲区强制刷新”的功能
注:对于写入文件这一块同样有这样的问题,这里不再做详细的讲述,但是给出下面的参考链接:http://blog.youkuaiyun.com/a312024054/article/details/46946237
3--缓冲区已满;
4--需要从缓冲区拿东西到时候,如执行scanf;
1)阻塞与非阻塞
A、阻塞函数:当该函数不执行完,函数所在线程就一直停止
B、阻塞调用与同步调用
同步调用:同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。
2)scanf、getchar、gets、fgets
这个链接中给了较好的例子以及比较,这里就不再重复叙述。
http://blog.chinaunix.net/uid-24567872-id-87648.html
(2)php中的flush与ob_flush
flush:把数据从PHP的缓冲中释放出来
ob_fflush:把不在缓冲中的或者说是被释放出来的数据发送到浏览器
所以当缓冲存在的时候,ob_flush()和flush()一般同时使用。
使用的顺序是:先用ob_flush(),后用flush()。