fflush(stdin)和fflush(stdout)和rewind(stdin)的区别和作用

理解:fflush(stdin)和fflush(stdout)和rewind(stdin)
小结论(多谢网友zhao4zhong1为我解答疑难):
1、在每个最后不带\n的printf后面加fflush(stdout);(对标准输出流进行清理,但是它并不是把数据丢掉,而是及时地打印数据到屏幕上。)
2、在每个不想受到输入(接收)缓冲区旧内容影响的scanf();【或者getchar();或者gets_s();】前面加rewind(stdin);(rewind()函数的作用是把文件的当前位置指针指向文件头。)
   或者添加fflush(stdin);(fflush(stdin)刷新标准输入缓冲区,把输入缓冲区里的东西丢弃[非标准])
3、另外请注意检查scanf的返回值。


一、fflush(stdin);函数
     fflush(stdin)比较容易理解,即清理标准输入流,把多余的仍未被保存的数据丢掉。
比如,下面这个小程序:

 
  1. void main()

  2. {

  3. int a;

  4. char str[10];

  5.  
  6. cin>>a;

  7. cout<<a<<endl

  8.  
  9.  
  10. // fflush(stdin),

  11. cin>>str;

  12. cout<<str<<endl;

  13. }


目地很简单:从stdin获得一个整数存入a,接着立马打印出来;从stdin获得一个字符串存入str,也立马打印出来。但是下面这种可能需要特别考虑:在首行输入了两个整数,在cin>>a之后,stdin缓冲还有一个整数没被读取。接下来,不等输入字符串,就直接把上面多出来的数字存入到str中去并打印。
某种程度上这是操作不规范造成的,但是程序应该要有健壮性,程序员应该提前预防这种不规范的操作。可以在程序界面上提示“请输入1个整数”,甚至有时候不厌其烦的强调和警告也必要。当然,本例为求简单,并不在UI友好方面做文章。这时,可以在cin>>str语句前插入fflush(stdin),如此一来就可以清空标准输入缓冲里多余的数据。


二、fflush(stdout);函数
小总结:
fflush(stdout)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上
printf("。。。。。。。。。。。");后面加fflush(stdout);可提高打印效率
fflush(stdout)跟fflush(stdin)类似,是对标准输出流的清理,但是它并不是把数据丢掉,而是及时地打印数据到屏幕上。为了更好的理解它,需要知道一个事实:标准输出是以『行』为单位进行的,也即碰到\n才打印数据到屏幕。这就可能造成延时,如下面这几行代码:

 
  1. <span style="font-size:12px;">int a;

  2.  
  3. printf_s("input one number:");

  4. fflush(stdout);\\#1

  5.  
  6. scanf_s("%d",&a);</span>


如果没有#1那行代码,在某些平台上就可能迟迟看不到"input one number"被打印到屏幕上来,因为它没有回车。这时候,fflush(stdout)就起到及时输出的作用。
但是在Windows平台上,似乎并看不出差别来。也即MSFT已经将stdout的输出改成及时生效了。
fflush函数被广泛使用在多线程、网络编程的消息处理中。
fflush(stdout):清空输出缓冲区,并把缓冲区内容输出


三、下面一段来自360搜索“fflush”:http://baike.so.com/doc/6745731.html
C和C++的标准里从来没有定义过 fflush(stdin)。也许有人会说:“可是我用 fflush(stdin) 解决了这个问题,你怎么能说是错的呢?”的确,某些编译器(如VC6)支持用 fflush(stdin) 来清空输入缓冲,但是并非所有编译器都要支持这个功能(linux下的gcc就不支持,经我的GCC4.6.2测试),因为标准中根本没有定义 fflush(stdin)。
MSDN 文档里也清楚地写着:
fflush on input stream is an extension to the C standard (fflush 操作输入流是对C标准的扩充)。
以下是 C99 对 fflush 函数的定义:
int fflush(FILE *stream);
如果stream指向输出流或者更新流(update stream),并且这个更新流最近执行的操作不是输入,那么fflush函数将把任何未被写入的数据写入stream指向的文件(如标准输出文件stdout)。否则,fflush函数的行为是不确定的。fflush(NULL)清空所有输出流和上面提到的更新流。如果发生写错误,fflush函数会给那些流打上错误标记,并且返回EOF,否则返回0。

由此可知,如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。故而使用 fflush(stdin) 是不正确的。(因此,我姑且得出一个结论:我们应尽量使用rewind(stdin);来取代fflush(stdin);函数,如此结论错误,还请网友指正。)


四清空键盘缓冲区的一种好方法! http://bbs.bccn.net/thread-248420-1-1.html
用  rewind(stdin);
语句可以达到很好的清空键盘缓冲区的作用。不用考虑太多其他因素。这是我在一本名为《软件开发:编程与设计(C语言版)》中所了解到的,作者是USA的David Conger。   
以前也了解到其他的清空键盘缓冲区的方法,如:用getchar();fflush(stdin);等。但感觉很麻烦,不好用,也不容易理解。而rewind(stdin)简单好用,而且是一种可移植的方法。  
举个例子:  

 
  1. <span style="font-size:12px;">#include <stdio.h>

  2. int main()

  3. {

  4. int i;

  5. char aString[3];

  6.  
  7. printf("Please enter some characters:"); /*先向键盘缓冲区里输入无用字符*/

  8. getchar();

  9. rewind(stdin); /*清空键盘缓冲区里的无用字符*/

  10. printf("Please enter 'OK': "); /*输入字符串“OK”*/

  11. for(i=0;i<2;i++) /*字符串aString接受字符串“OK”*/

  12. {

  13. aString[i]=getchar();

  14. }

  15. aString[i]='\0';

  16. puts(aString); /*输出字符串aString*/

  17. return(0);

  18. } </span>


Microsof Visual C++下调试结果:
输入:abcdefghijk回车OK回车 
输出:OK  之前缓冲区里的abcdefghijk垃圾字符都被清空了。 


下面向新手解释一下rewind(stdin);的工作原理。
C语言把键盘,显示器等设备当做文件来处理,也就是说从键盘输入相当于从一个文件中读入,向显示器输出相当于向一个文件写出。
而stdin是C标准库定义的标准文件之一,它与键盘相关联。我一般把它理解为指向键盘这个“文件”的指针。
而rewind()函数的作用是把文件的当前位置指针指向文件头。
两者结合,rewind(stdin);的作用也就是把“指向键盘(一个文件)的指针从当前位置挪到键盘(一个文件)开头”,相当于抛弃了当前键盘缓冲区中的数据,重新开始输入。 
虽然并不是真正的把缓冲区里的数据全部清掉,但却起到了清空键盘缓冲区的效果。

五、rewind(stdin)和fflush(stdin) 的有什么区别(意义,用法等等)  :http://wenda.so.com/q/1378244901061364


语法上 , 
rewind(stdin) 是把文件指针回绕到文件起始处。 
fflush(stdin) 是把文件输入缓冲区清0。 
stdin 是标准输入设备(输入流),通常是键盘。(但也可以是通过转向的文本文件。) 
------------ 
昨天有人问,数入123,第2句输入语句不能工作

 
  1. int a1;

  2. char s[20];

  3. scanf("%d",&a1); //第一句输入语句

  4. scanf("%[^'\n']",s); // 第2句输入语句

  5. printf("a1=%d\n s=%s\n",a1,s);


答:添上fflush(stdin); 就可以了。  
int a1; char s[20]; 
scanf("%d",&a1); //第一句输入语句 
rewind(stdin); 
// fflush(stdin); 
scanf("%[^'\n']",s); // 第2句输入语句 
printf("a1=%d\n s=%s\n",a1,s); 
添上 fflush(stdin); 效果相同。

猜你喜欢

转载自blog.csdn.net/qq_41598072/article/details/81510858