2014-11-22 22 views
0

我正在使用我創建的宏來清除scanf後的緩衝區,但我被告知這不是一個好主意,因爲「很多原因」。你能解釋一下爲什麼以及如何清理它?我知道使用fflush(stdin)是一個非常糟糕的主意,因爲它沒有被定義。使用C中的宏清除緩衝區是不是一個好主意?

這是我用的宏:

#define CLEAR_BUFFER do { c = getchar(); } while (c != '\n' && c != EOF); 

而且也,另一個問題:在「現實世界」中使用scanf函數?如果是的話,人們如何清理緩衝區?

感謝

+0

如果您在閱讀某些內容後遇到空格或換行符問題,可以在'%d','%f'或類似內容之前放置一個空格,例如, 'scanf(「%d」,x)' – humodz 2014-11-22 13:24:59

+0

對於用戶輸入,使用'fgets()'來獲取數據並很好地處理線路緩衝輸入流。 – pmg 2014-11-22 13:32:42

+1

@ pmg爲健壯的代碼,fgets也需要清理,因爲行可能會超過緩衝區大小 – 2014-11-22 14:00:14

回答

7

的想法是好的,雖然執行還有待改進:

#define CLEAR_BUFFER() do { int ch; while ((ch = getchar()) != EOF && ch != '\n') {} } while (0) 

你的版本沒有申報c並能正確使用。如果你不熟悉do...while(0)see here

甚至比這兩個更好的方式是編寫一個函數:

void clear_buffer(void) 
{ 
    int ch; while ((ch = getchar()) != EOF && ch != '\n') {} 
} 

如果你有興趣來區分EOL是否發生或出現了錯誤,您能做出這樣的回報bool(但調用代碼無論如何可以檢查feof(stdin) || ferror(stdin))。

在C99中,這可能是內聯函數,但如果您在C90中並使其非內聯,那麼這不是一個大問題。


對於問題的第二部分:我從來沒有使用scanf,我在清理我剛纔所描述的方式緩衝。其他人可能會以不同的方式做到這一點,這更多的是個人偏好問題。

+0

我寧願'clear_buffer()'return'ch' ...以便調用代碼可以很容易地檢測到'EOF'。 – pmg 2014-11-22 13:29:11

+0

在獲取所需輸入之後使用'%* c'敲掉換行符是不是一個好主意? – Gopi 2014-11-22 13:33:00

+0

我更喜歡原來的'do while'方法,對我來說似乎更具可讀性。 – 2014-11-22 13:33:23