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)比較容易理解,即清理標準輸入流,把多余的仍未被保存的數據丟掉。
比如,下面這個小程序:
-
void main() -
{ -
int a; -
char str[10]; - ?
-
cin>>a; -
cout<<a<<endl - ?
- ?
-
// fflush(stdin), -
cin>>str; -
cout<<str<<endl; -
}
目地很簡單:從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才打印數據到屏幕。這就可能造成延時,如下面這幾行代碼:
-
<span style="font-size:12px;">int a; - ?
-
printf_s("input one number:"); -
fflush(stdout);\\#1 - ?
-
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)簡單好用,而且是一種可移植的方法。 ?
舉個例子: ?
-
<span style="font-size:12px;">#include <stdio.h> -
int main() -
{ -
int i; -
char aString[3]; - ?
-
printf("Please enter some characters:"); /*先向鍵盤緩沖區里輸入無用字符*/ -
getchar(); -
rewind(stdin); /*清空鍵盤緩沖區里的無用字符*/ -
printf("Please enter 'OK': "); /*輸入字符串“OK”*/ -
for(i=0;i<2;i++) /*字符串aString接受字符串“OK”*/ -
{ -
aString[i]=getchar(); -
} -
aString[i]='\0'; -
puts(aString); /*輸出字符串aString*/ -
return(0); -
} </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句輸入語句不能工作
-
int a1; -
char s[20]; -
scanf("%d",&a1); //第一句輸入語句 -
scanf("%[^'\n']",s); // 第2句輸入語句 -
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); 效果相同。
總結
以上是生活随笔為你收集整理的fflush(stdin)和fflush(stdout)和rewind(stdin)的区别和作用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: fprintf()中的stderr解析
- 下一篇: OpenGL学习脚印: 投影矩阵和视口变