2016-09-23 59 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);