最近老陌偶然從論壇的一個帖子裏發現了以前忽略了的一個知識點,看了一些資料後不得不感慨自己之前對於 scanf 對於 C 的理解實在太淺顯了!最後我打算把本次學習所得寫出來……
double get_input(void)
{
double a;
char ch;
while(scanf("%lf",&a)!=1)
{
while ((ch=getchar())!='\n')
putchar(ch);
printf("\nEnter a number\n");
}
return a;
}
while(scanf("%lf",&a)!=1) // 輸入的是double內容,那麼while循環體不執行; 如果不是double,鍵盤緩衝區的內容並沒有變化,還是原來的內容,所以一直在這兒死循環
while(scanf("%lf",&a)!=1) { // 輸入的不是一個double類型數據, 會進入這個while循環體
while ((ch=getchar())!='\n') // 把緩衝區的字符一個一個的提取出來, 包括最後的回車符, 也就是放棄了這一整行的數據了
後面的這個函數,因爲可以把鍵盤緩衝區清空,讓用戶重新輸入數據,所以可以繼續進行下去
前面的那個函數,因爲沒有清理緩衝區, 所以讀取double的條件始終無法達到
C標準規定 fflush()函數是用來刷新輸出(stdout)緩存的。對於輸入(stdin),它是沒有定義的。但是有些編譯器也定義了 fflush( stdin )的實現,比如微軟的VC。其它編譯器是否也定義了 fflush( stdin )的實現應當查找它的手冊。GCC編譯器沒有定義它的實現,所以不能使用 fflush( stdin )來刷新輸入緩存。
對於沒有定義 fflush( stdin )的編譯器,可以使用 fgets()函數來代替它(比用 getchar()、scanf()等函數通用性好)。可以這樣忽略輸入流中留下的回車等其它輸入,從而使下一次的輸入總保持一個“乾淨”的狀態。(這個是任何平臺下都可以的)
功能:清空輸入緩衝區,通常是爲了確保不影響後面的數據讀取(例如在讀完一個字符串後緊接着又要讀取一個字符,此時應該先執行fflush(stdin);)。
fflush(stdin)僅適用於部分編譯器(如VC6),但是並非所有編譯器都要支持這個功能(如gcc3.2)。這是一個對C標準的擴充。在linux下用的是gcc,因此可能不起作用。
鍵盤的內部有一塊微處理器,它控制着鍵盤的全部工作,比如主機加電時鍵盤的自檢、掃描,掃描碼的緩衝以及與主機的通訊等等。當一個鍵被按下時,微處理器便根據其位置,將字符信號轉換成二進制碼,傳給主機和顯示器。如果操作人員的輸入速度很快或CPU正在進行其它的工作,就先將鍵入的內容送往內存中的鍵盤緩衝區,等CPU空閒時再從緩衝區中取出暫存的指令分析並執行
scanf支持正則
scanf(“%*[^\n]%*c”);
參考資料: