2015-09-04 50 views
3

我一直認爲,「在緩衝區‘\ n’」的問題只發生,當我們讀取字符, 不過,我在這個問題上用下面的代碼絆倒:我們什麼時候需要清除scanf緩衝區?

int main(int argc, char** argv){ 
    int height = 0, width = 0; 

    while(height < 1 || height > 10|| width < 1 || width > 15){ 
     printf("Please insert the height(1~10) and width(1~15) of the parallelogram (integers): "); 
     if(scanf("%d %d", &height, &width) != 2){ 
      height = width = 0; 
     } 
    } 
    return 0; 
} 

如上所述,我只有用scanf讀取整數, ,但是當我輸入一些無效的代碼時,這段代碼仍然陷入無限循環。 如果我清除緩衝區,它是固定的。

所以我的問題是,這是「'\ n'在緩衝區」發佈一般事情嗎? 還是隻有特殊用途纔會發生? 如果只發生特殊用法,是否需要遵循一些通用指南?

+3

如果'scanf'不返回'2',則需要清除緩衝區。然後在緩衝區中有一些不能被解釋爲'int'的字符,例如一個字母。空格(以及開頭處的新行)將被忽略。 – mch

+0

請注意,這是**不是**換行符的問題,但無效字符留在'stdin'和'scanf'中,看到它們,失敗,重複...... FYI,'%d'跳過前導空白字符。 –

回答

4

一般指導原則是不使用*scanf()用戶輸入。您從格式錯誤的輸入中正常恢復的能力太有限了,錯誤出現的可能性太高了(正如SO的絕對數量與*scanf()相關的問題一樣)。 *scanf()函數族最適用於只讀格式良好的輸入(即先前由您自己的應用程序編寫的數據)。

無論如何,用戶輸入是基於行的,至少如果您依賴標準輸入功能。

所以使用fgets()來讀取一整行輸入,然後解析它在內存中。像strtol()strtod()這樣的函數可以給出非常具體的反饋,在這一點上它們停止解析,您可以跳過並嘗試不同的解析,您可以使用標準的所有string-handling functions來挑選用戶的輸入。如果事情變成梨形,您可以在錯誤消息中重複整行輸入,在您喜歡的解析嘗試中添加任何信息。