【问题标题】:Clear input buffer after fgets() in C在 C 中的 fgets() 之后清除输入缓冲区
【发布时间】:2016-12-10 14:44:00
【问题描述】:
#include <stdio.h>
int main()
{
  char name[10];
  for(int i=0;i<=10;i++)
  {
    printf("Who are you? ");
    if(fgets(name,10,stdin)!=NULL)
    printf("Glad to meet you, %s.\n",name);
  }
  return(0);
}

当我输入的内容超过 10 个字符时,循环会跳过。

Who are you? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaa

我想我想从剩余的字符中清除输入缓冲区。最好的方法是什么...?

【问题讨论】:

    标签: c inputstream fgets fflush


    【解决方案1】:

    您需要使用类似以下的方式查找\n

    /* flush unread input buffer */
    while( ! strchr( name, '\n' ) )
        if( ! fgets(name,(sizeof name),stdin) )
            break;
    

    注意:不确定您认为这是错误还是功能,但短名称将包括最后的 \n。结果如下:

    Glad to meet you SSS
    .
    

    【讨论】:

    • 这是个好主意,除了fgets() 的额外调用会更好(IMO),使用与name[] 不同的缓冲区。 OTOH @Nikhil George 在这种情况下不清楚 name[] 的内容。
    【解决方案2】:

    检查fgets() 是否获得了'\n'。如果没有'\n',则当前行中的一些字符还没有被读取。你可以直接忽略它们。

        printf("Who are you? ");
        if (fgets(name, 10, stdin) != NULL) {
            if (!strchr(name, '\n')) {
                // consume rest of chars up to '\n'
                int ch;
                while (((ch = getchar()) != EOF) && (ch != '\n')) /* void */;
                if (ch == EOF) /* input error */;
                printf("Glad to meet you, %s.\n", name);
            } else {
                printf("Glad to meet you, %s.", name); // name includes ENTER
            }
        }
    

    【讨论】:

    • 不清楚为什么if (ch == EOF) 被认为是一个错误,因为可能很简单,stdin 已关闭。 (例如重定向输入:program_foo &lt; input.txt。)
    • @chux:您可以检查ferror() 和/或feof() 以确保。对我来说,一行包括 ENTER。如果文件中的最后一个字符不是'\n',则该文件将以非行结束。
    【解决方案3】:

    检查name中是否存在换行符。

    #include <stdio.h>
    #include <string.h>
    
    int main(void){
        char name[10];
    
        for(int i=0;i<=10;i++){
            printf("Who are you? ");
            if(fgets(name,10,stdin)){
                char *p;
                if(p=strchr(name, '\n')){//check exist newline
                    *p = 0;
                } else {
                    scanf("%*[^\n]");scanf("%*c");//clear upto newline
                }
                printf("Glad to meet you, %s.\n", name);
            }
        }
        return(0);//Parentheses is not necessary
    }
    

    【讨论】:

    • 善用scanf("%*[^\n]");scanf("%*c");而不是不正确的scanf("%*[^\n]%*c");
    【解决方案4】:

    来自fgets 的文档(强调我的):

    从流中读取字符并将它们作为 C 字符串存储到 str 直到 (num-1) 个字符被读取或换行符或 到达文件末尾,以先发生者为准

    因此,您的输入(超出缓冲区)以 9 个字符(+1 个空终止字符)的块形式读取。

    您需要反复调用fgets,直到最后读取的字符是换行符(\n)。

    【讨论】:

    • 问题是当输入长度限制的字符时,它会让gets等待..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-08
    • 2013-01-01
    • 2011-12-15
    相关资源
    最近更新 更多