1. 爲何 fflush(stdin) 是錯的linux
首先請看如下程序:ios
#include <stdio.h>ide
int main( void )函數
{操作系統
int i;ci
for (;;) {文檔
fputs("Please input an integer: ", stdout);get
scanf("%d", &i);input
printf("%d\n", i);編譯器
}
return 0;
}
這個程序首先會提示用戶輸入一個整數,而後等待用戶輸入,若是用戶輸入的是整數,程序會輸出剛纔輸入的整數,而且再次提示用戶輸入一個整數,而後等待用戶輸入。可是一旦用戶輸入的不是整數(如小數或者字母),假設 scanf 函數最後一次獲得的整數是 2 ,那麼程序會不停地輸出「Please input an integer: 2」。這是由於 scanf("%d", &i); 只能接受整數,若是用戶輸入了字母,則這個字母會遺留在「輸入緩衝區」中。由於緩衝中有數據,故而 scanf 函數不會等待用戶輸入,直接就去緩衝中讀取,但是緩衝中的倒是字母,這個字母再次被遺留在緩衝中,如此反覆,從而致使不停地輸出「Please input an integer: 2」。
也許有人會說:「竟然這樣,那麼在 scanf 函數後面加上‘fflush(stdin);’,把輸入緩衝清空掉不就好了?」然而這是錯的!C和C++的標準裏歷來沒有定義過 fflush(stdin)。也許有人會說:「但是我用 fflush(stdin) 解決了這個問題,你怎麼能說是錯的呢?」的確,某些編譯器(如VC6)支持用 fflush(stdin) 來清空輸入緩衝,可是並不是全部編譯器都要支持這個功能(linux 下的 gcc 就不支持),由於標準中根本沒有定義 fflush(stdin)。MSDN 文檔裏也清楚地寫着fflush on input stream is an extension to the C standard(fflush 操做輸入流是對 C 標準的擴充)。固然,若是你絕不在意程序的移植性,用 fflush(stdin) 也沒什麼大問題。如下是 C99 對 fflush 函數的定義:
int fflush(FILE *stream);
若是 stream 指向輸出流或者更新流(update stream),而且這個更新流
最近執行的操做不是輸入,那麼 fflush 函數將把這個流中任何待寫數據傳送至
宿主環境(host environment)寫入文件。不然,它的行爲是未定義的。
原文以下:
int fflush(FILE *stream);
If stream points to an output stream or an update stream in which
the most recent operation was not input, the fflush function causes
any unwritten data for that stream to be delivered to the host environment
to be written to the file; otherwise, the behavior is undefined.
其中,宿主環境能夠理解爲操做系統或內核等。
由此可知,若是 stream 指向輸入流(如 stdin),那麼 fflush 函數的行爲是不肯定的。故而使用 fflush(stdin) 是不正確的,至少是移植性很差的。
2. 清空輸入緩衝區的方法
雖然不能夠用 fflush(stdin),可是咱們能夠本身寫代碼來清空輸入緩衝區。只須要在 scanf 函數後面加上幾句簡單的代碼就能夠了。
/* C 版本 */
#include <stdio.h>
int main( void )
{
int i, c;
for ( ; ; )
{
fputs("Please input an integer: ", stdout);
scanf("%d", &i);
if ( feof(stdin) || ferror(stdin) )
{ /* 若是用戶輸入文件結束標誌(或文件已被讀完), */
/* 或者發生讀寫錯誤,則退出循環 */
/* do something */
break;
}
/* 沒有發生錯誤,清空輸入流。 */
/* 經過 while 循環把輸入流中的餘留數據「吃」掉 */
while ( (c = getchar()) != '\n' && c != EOF ) ;
/* 使用 scanf("%*[^\n]"); 也能夠清空輸入流, */
/* 不過會殘留 \n 字符。 */
printf("%d\n", i);
}
return 0;
}
/* C++ 版本 */
#include <iostream>
#include <limits> // 爲了使用numeric_limits
using std::cout;
using std::endl;
using std::cin;
using std::numeric_limits;
using std::streamsize;
int main()
{
int value;
for ( ; ; )
{
cout << "Enter an integer: ";
cin >> value;
if ( cin.eof() || cin.bad() )
{ // 若是用戶輸入文件結束標誌(或文件已被讀完),
// 或者發生讀寫錯誤,則退出循環
// do something
break;
}
// 讀到非法字符後,輸入流將處於出錯狀態,
// 爲了繼續獲取輸入,首先要調用 clear 函數
// 來清除輸入流的錯誤標記,而後才能調用
// ignore 函數來清除輸入流中的數據。
cin.clear();
// numeric_limits<streamsize>::max() 返回輸入緩衝的大小。
// ignore 函數在此將把輸入流中的數據清空。
// 這兩個函數的具體用法請讀者自行查詢。
cin.ignore( numeric_limits<streamsize>::max(), '\n' );
cout << value << '\n';
}
return 0;
}
參考資料:
ISO/IEC 9899:1999 (E) Programming languages— C 7.19.5.2 The fflush function
The C Programming Language 2nd Edition By Kernighan & Ritchie
ISO/IEC 14882(1998-9-01)Programming languages — C++
@2006-2-26 22:48 hxmzlgz
fflush(stdin);語句的做用
#include
#include
void main()
{float com=0.0,sale;int i;
char grade;
clrscr();
printf("\n Enter sale:");
scanf("%f",&sale);
fflush(stdin);
printf("\n Enter grade:");
scanf("%c",&grade);
if(sale>10000)
if(grade=='A')
com=sale*0.1 ;
else
com=sale*0.08 ;
else
com=sale*0.05;
printf("\n Com=%f",com);
}