2010-10-06 71 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