【问题标题】:clearing stdin buffer ?清除标准输入缓冲区?
【发布时间】:2012-02-26 22:24:07
【问题描述】:

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

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

然后从主函数调用:

dump_line(stdin);

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

【问题讨论】:

  • 缓冲区未填满。它只包含一个您尚未阅读的行终止符,并且您发布的循环已读取。

标签: c


【解决方案1】:

如果我真的需要在纯 C 中执行,这是我用于用户输入的旧 sn-p:

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;
}

它从标准输入中检索bsize 数量的字母并将它们存储到给定的缓冲区中。 stdin 输入缓冲区中的内容将被自动清理。它还会从输入数据中删除换行符(\r 和 \n)。

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

【讨论】:

    【解决方案2】:

    它只是将 fgetc(stdin) 的值分配给“ch”

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

    【讨论】:

    • 哦,好吧,我想知道为什么教程完全忘了提及它。谢谢:d
    【解决方案3】:

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

    它是如何工作的:

    1. 调用fgetc(stdin),并将结果赋值给ch
    2. 如果ch 不等于EOF'\n',请转到1。

    当循环停止时,会出现以下两种情况之一:要么你刚刚吃掉了标记当前行结尾的字符(阅读:你现在在下一行),要么stdin 是为空,您将不再获得任何输入。 (后者在交互式应用程序中是不常见的,但在人们从其他地方将内容导入您的应用程序时很常见。做好准备。)

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        这是同一个循环,但写法不同,也许这可以解释它:

        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 */
            }
        }
        

        【讨论】:

          【解决方案6】:

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

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

          【讨论】:

            【解决方案7】:

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

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

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

            【讨论】:

              猜你喜欢
              • 2023-04-08
              • 2013-07-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多