2012-12-20 36 views
2

我是一名軟件工程專業的學生,​​爲了在下個學期更好,我正在聖誕節休息,我一直在編寫各種控制檯應用程序來練習。然而,我遇到了一個問題,我需要從用戶那裏得到整數輸入。我一直在使用fgetsstdin獲取字符串,然後使用sscanf獲取整數(其工作正常),但是如果用戶輸入的數量多於我的緩衝區大小,則會在流中留下拖尾字符(包括換行符跳過我的下一次致電fgets)。我環顧四周,發現大多數人似乎建議while(getchar() != '\n');,但是這會導致我的問題,因爲如果沒有換行字符將被消耗一個不必要的掃描輸入發生。嵌入式輸入C

實施例:

int ch; 
char* buffer = (char*)malloc(BUFSIZ*sizeof(char)); 
while((ch = getchar()) != '\n' && ch != EOF); 
fgets(buffer,BUFSIZ*sizeof(char),stdin); 

如果緩衝器不是太小和沒有尾隨字符保持在流中,然後有一個不必要的getchar()造成輸入。

輸出:

A 

A 

You typed A 

Intended Output: 

A 

You typed A 

我希望我做這個很清楚,我感謝所有幫助。

+0

請不要使用malloc來分配緩衝區,除非它非常大。遲早,你會忘記釋放它。 Windows和Linux的堆棧(在用戶空間中)是幾兆字節。 如果稍後需要將輸入數據存儲到某個有組織的數據結構中,則可能需要malloc並釋放該結構。但是在本地使用的小緩衝區上調用malloc是一個不錯的選擇。 –

+0

他可能需要返回它,你不知道上下文。如果沒有被返回, –

+0

可以使用alloca。當函數返回時,它會得到釋放,但實際上只是聲明一個數組可能是要走的路。 – kdubs

回答

6

檢查您閱讀的字符串是否包含換行符。

  • 如果有換行符,則不需要清除輸入。
  • 如果沒有換行符,請閱讀,直到遇到一個換行符。

在Unix平臺上,這個循環是合理的:

int c; 
while ((c = getchar()) != EOF && c != '\n') 
    ; 

注意EOF測試與你報什麼(在這個問題的文本相比,這是你在你的代碼段引用的,但它分散在這裏兩行,這通常是更好的可讀性)。我會在fgets()之後做這個'吞噬',而不是在下一個之前。

在帶有Microsoft編譯器和庫的Windows上,如果您有這樣的想法,可以使用fflush(stdin)進行操作。這有記錄的行爲(請參閱MSDN網站)。在Unix上,嘗試fflush(stdin)會產生未定義的行爲 - 不要這樣做。

+1

「在Windows上」 - 對於某些編譯器也許;使用Cygwin下的gcc,它不會刷新輸入。 –