【C】學習筆記:scanf與鍵盤輸入緩衝區

最近老陌偶然從論壇的一個帖子裏發現了以前忽略了的一個知識點,看了一些資料後不得不感慨自己之前對於 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”);

 

參考資料:

鍵盤緩衝區

scanf 清緩衝區的問題 

fflush(stdin)

scanf()中清除輸入緩衝區的幾種方法歸納

『踩坑記錄』scanf輸入緩衝區的問題

c語言輸入輸出緩衝區的概念

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章