清除stdin缓冲区?

时间:2012-02-26 22:24:07

标签: c

我正在编写一些代码并使用fgets来获取用户输入。然后我在我的代码上写了一个循环,一直要求用户输入,直到用户打印退出。但它第二次问,它写了“请输入你的输入”2次而不是1次,并没有等到我第一次输入。 所以,我用谷歌搜索它,发现stdin缓冲区已经填满,必须清除它。 我找到了这个解决方案:

void dump_line(FILE * fp) {
    int ch;
    while ((ch = fgetc(fp)) != EOF && ch != '\n') {
        /* null body */;
    }
}

然后从主函数调用:

dump_line(stdin);

我很难理解它。据我所知,它只是赋予“ch”fgetc(stdin)的值。我只是无法理解如何将fgetc(stdin)分配给“ch”清除缓冲区。 非常感谢您的帮助!

7 个答案:

答案 0 :(得分:4)

如果我真的需要在纯C中使用,那么这是我用于用户输入的旧片段:

int get_line(char *buffer, int bsize)
{
    int ch, len;

    fgets(buffer, bsize, stdin);

    /* remove unwanted characters from the buffer */
    buffer[strcspn(buffer, "\r\n")] = '\0';

    len = strlen(buffer);

    /* clean input buffer if needed */
    if(len == bsize - 1)
        while ((ch = getchar()) != '\n' && ch != EOF);

    return len;
}

它从stdin中检索bsize个字母并将它们存储到给定的缓冲区中。 stdin输入缓冲区中剩余的东西将自动清除。它还从输入数据中删除换行符(\ r和\ n)。

函数返回成功读取的字符数。

答案 1 :(得分:2)

  

它只是将“ch”指定为fgetc(stdin)的值

调用fgetc具有副作用,即从该文件流中读取并删除字符。

答案 2 :(得分:1)

fgetc(stdin)分配给ch并不是清除缓冲区的原因。这是fgetc(stdin)的实际调用。每次调用(因此,循环的每次迭代)都会从stdin中获取一个字符。

工作原理:

  1. 致电fgetc(stdin),并将结果分配给ch
  2. 如果ch不等于EOF'\n',请转到1.
  3. 当循环停止时,两件事之一将成立:要么你刚刚吃了标记当前行结束的字符(读:你现在在下一行),或{{1}是空的,你不会再得到任何输入。 (后者在交互式应用程序中是不常见的,但是当人们从其他地方将内容传输到您的应用程序时很常见。为此做好准备。)

答案 3 :(得分:0)

fgetc()从缓冲区中获取一个字符。此代码从缓冲区中读取字符,直到文件结束或到达换行符。

答案 4 :(得分:0)

这是相同的循环,但写的方式不同,也许这可以解释它:

void dump_line(FILE * fp) { /* dump a line from fp */
    int ch; /* temporary storage for character */

    while (1) {
        ch = fgetc(fp); /* read char from fp, this removes it from the stream */

        if (ch == EOF)  /* break if we reached END-OF-FILE */
            break;

        if (ch == '\n') /* break if we reached a newline, because */
            break;      /* we have succesfully read a line */
    }
}

答案 5 :(得分:0)

清除缓冲区的另一个例子:

char ch[1];
while(1){
    ch[0] = fgetc(stdin);
    if(ch[0] == '\n' || ch[0] == EOF) break;
}

答案 6 :(得分:-1)

这是我想出的两行解决方案,希望对您有所帮助。

char ch;
while ((ch = fgetc(stdin)) == EOF || ch == '\n');

fgetc既可以读取STDIN缓冲区,也可以从中删除。它将继续这样做,直到到达EOF或换行符为止,这意味着STDIN现在为空。