2010-10-06 126 views
4

我有使用fgets的問題。該循環應該讀取一行最大值。 19個字符,分析此char數組,然後等待下一個輸入。 問題是,如果輸入的行放入了19個字符,fgets將填充其餘字符,直到輸入Ctrl-D或換行符,從而啓動一個沒有新輸入的新循環。讀取19個字符後,輸入(stdin)應該以某種方式刷新,因此循環可以從乾淨的版本開始。任何人都可以解決這個問題?C,沖洗stdin

char str[20]; 
while((fgets(str, 20, stdin) != NULL)) { 
    puts(str);  //monitoring str 

    if(str[0] == 'q') break; 
} 

實施例中使用:

hola hola      //user inputs 9 chars + newline 
hola hola      //puts writes 

hoo hoo hoo hoo hooh    //user inputs 20 chars + newline 
hoo hoo hoo hoo hoo    //puts writes 
h        // 

回答

2
char str[21]; /* read one extra character */ 
while (fgets(str, 21, stdin) != NULL) { 
    /* if line too long, truncate and swallow the rest of the line */ 
    if (strlen(str) > 19) { 
     str[19] = '\0'; 
     while (getchar() != '\n' && !feof(stdin)) 
      ; 
    } 

    puts(str); 
    if(str[0] == 'q') break; 
} 
+0

感謝,我認爲會做的伎倆。 – DoggyDoo 2010-10-06 19:42:04

4

scanf("%*[^\n]\n");可能是最簡單的可能性之一。

+0

我想你必須通過一個字符緩衝區參數。此解決方案不檢查緩衝區溢出,是嗎?天哪,我的C很生鏽。 – xpmatteo 2010-10-06 19:33:55

+0

@xpmatteo:它不需要緩衝區參數。來自man scanf:「一個可選的'*'分配抑制字符:scanf()根據轉換規範讀取輸入,但丟棄輸入。不需要相應的指針參數」 – 2010-10-06 19:37:16

+0

正如@Giuseppe指出的那樣,美的一部分這是你不必傳遞一個緩衝區。由於沒有緩衝區,所以也不存在緩衝區溢出的可能性。不要責怪自己沒有意識到這一點,但這種轉換絕對是在深奧的一面。 – 2010-10-06 19:40:07

-1

嘗試:

fgets(str, 2000, stdin) 

然後截斷STR至19 :-)

+3

......並希望用戶永遠不會粘貼2MB長的行! – 2010-10-06 19:42:38

+0

True :-)但這是一個快速解決方案。 – xpmatteo 2010-10-08 11:28:23

0

另一種可能的變體用於fgets的約束()是所使用的唯一的輸入,並在循環水平。這與拉斯曼提出的非常相似。所以,我想我會爲他投票:-)

#include <stdio.h> 

int main(){ 
    char str[20]; 
    int skip = 0; 
    str[19] = 1; 
    while (fgets(str, 20, stdin)) { 
     // just ignore lines of more than 19 chars 
     if (str[19] == 0){ 
      str[19] = 1; 
      skip = 1; 
      continue; 
     } 
     // also skip the end of long lines 
     if (skip) { 
      skip = 0; 
      continue; 
     } 
     // monitor input 
     puts(str); 
     // stop on any line beginning with 'q' 
     if (str[0] == 'q'){ 
      break; 
     } 
    }; 
} 
0

看一看fpurge:

fpurge(stdin); 
+1

...這是非標準的... – DevSolar 2010-10-21 18:12:11