2016-09-23 66 views
0

說我有下面的代碼段清潔標準輸入緩衝區的問題

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <string.h> 

int main() { 
    char choice; 
    char name[5] = ""; 
    do { 
     printf("a = new name or anything else to quit\nChoice: "); 
     choice = getchar(); 
     //not doing any error handling....assuming you only click 'a' 
     switch (choice) { 
      case 'a': 
       getchar(); 
       printf("Enter a name which is 4 characters or less: "); 
       fgets(name, 5, stdin); 
       printf("Name: %s\n", name); 
       char c; 
       while ((c = getchar()) != '\n' && c != EOF); 
       printf("%c", c); 
       c = '\0'; 
       break; 
      default: 
       break; 
     } 

    } while (choice == 'a'); 
    printf("Ending.....press enter now"); 
    getchar(); 
    return 0; 
} 

什麼,我試圖在這裏的測試是清除緩衝區時,我有4個以上的字符輸入到。它可以正常工作,只要我有一個4字符或更多的名字,但是當我輸入3個字符或更少時,問題就變成了while循環。它期望來自stdin緩衝區的getchar(),但是這是空的。有什麼辦法解決這個問題?

+0

我真的不明白你問的是什麼,但getchar()返回int,而不是char。你似乎正在尋找最多5個字符後看到換行符,這似乎是好的,但我會使用fgetc而不是getchar(),只是因爲你使用fgets,並且如果由於某種原因getchar()不使用相同緩衝區作爲fgets(),然後所有投注都關閉。另外,我認爲fgets不必null來終止字符串,所以你可能想在那裏傳遞4而不是5,然後設置name [4] ='\ 0';之後。這可能會對您有所幫助,或者您可能想要重新提出問題。 – Alex

+0

我輸入名稱「abc」,例如.....名稱[3]中存儲的內容將是'\ n'。現在,因爲此時緩衝區中沒有任何內容,while循環將從空緩衝區中獲取getchar(),這意味着我卡在那裏。 –

回答

1

您需要檢查name是否包含換行符。如果是這樣,緩衝區中沒有任何東西,你不需要刷新它。

fgets(name, 5, stdin); 
    printf("Name: %s\n", name); 
    if (strchr(name, '\n') == NULL) { 
     int c; 
     while ((c = getchar()) != '\n' && c != EOF); 
    } 
+0

ahhhh這將工作....如果字符串不包含'\ n',那麼我知道它在緩衝區! –

1

我們在my answer to your previous question的評註中已經討論過了。如果緩衝區中有空間,fgets()將使用終止換行符,將其放入緩衝區。您可以通過在緩衝區中查找換行符來確定它是否已經這樣做。如果你找到一個,然後

  1. 你可能想將其刪除 - 用'\0'替換它,例如。

  2. 您應該避免嘗試排除輸入行的尾部,因爲流已經前進到下一行。

+0

即時消息說,如果名稱是'ab \ n'.... fgets不會將該新行字符放入緩衝區...它保留爲名稱[2]。在你之前的迴應是我正在尋找的 –

+0

@YusufJama,dbush的回答和我的完全一樣。不過,無論如何,如果你喜歡他的話,那就是你應該接受的。 –

+0

在你的[最近的問題](http://stackoverflow.com/questions/39667485/why-use-eof-to-check-if-stdin-buffer-is-cleared)你被告知,如果輸入是足夠短,'newline'將在輸入字符串中。然後,緩衝區中沒有任何內容可以清除,但只有當條目中不存在「換行符」時纔會清除。在問他們如何工作之前,請閱讀您使用的每個功能的手冊頁。 –

0
  1. 檢查的fgets()結果。除非代碼如此,否則使用name的內容可能是未定義的行爲。避免幻數:使用sizeof name

     // fgets(name, 5, stdin); 
         if (fgets(name, sizeof name, stdin) == NULL) Handle_EOF(); 
    
  2. 尋找在name[]一個潛在'\n'

     char *eol = strchr(name, '\n'); 
    
  3. 如果找到一個,覆蓋空字符,否則消耗行的其餘部分

     if (eol) { 
          *eol = '\0'; 
         } else { 
          int ch; 
          while ((ch = getchar()) != '\n' && ch != EOF); 
         } 
    
  4. 打印name[]

     printf("Name: %s\n", name);