【问题标题】:C: Stdin - Removing Excess DataC: Stdin - 删除多余的数据
【发布时间】:2014-08-27 12:10:26
【问题描述】:

短版

我想摆脱来自stdin 的过多用户输入,但我知道不推荐使用fflush(stdin)。我找到了这个替代品:

int ch;
while ((ch = getchar()) != '\n' && ch != EOF);

但是,如果没有多余的数据要删除,这将删除用户的下一个输入。如何检查stdin是否有数据要删除,以便我可以选择是否使用这种清除缓冲区的方法?

带解释的长版

我正在用 Obj-C/C 制作一个命令行工具。

我了解声明char str[SIZE] 语法会将SIZE 字节的内存分配给str。我想为每个变量分配尽可能少的内存以避免浪费内存。

但是,如果您使用 fgets(str,sizeof(str),stdin) 并且输入 更多 字节的输入,fgets 将占用您输入的 SIZE 字节并将其存储在 str 中,将所有其他数据留在缓冲区中。如果您再次调用fgets,剩余的数据将存储在您作为fgets 的第一个变量传递的变量中,并且基本上完全跳过了提示。我不希望这种情况发生。一个常见的解决方案是fflush(stdin)

各种互联网资源(包括 SO)表明使用 fflush(stdin) 不是一个好主意,因为当您将输入流作为参数传递时它是“未定义的”。

我在CProgramming.com找到了这个替代品

int ch;
while ((ch = getchar()) != '\n' && ch != EOF);

但是,同一消息来源提到,如果stdin 中没有多余的数据要删除,它将在用户的下一次输入时执行此操作,因此第二次调用fgets 可能不会收到所有数据。

如何查看stdin中是否有数据,以便决定是否清除?

【问题讨论】:

  • 您无法真正知道输入缓冲区中是否存在“多余”数据。如果你使用例如scanf 读取输入,然后大多数格式会跳过前导空格,对于两种格式,您可以通过在格式中插入前导空格来解决它。
  • 至于您担心fgets 没有得到所有内容,请记住fgets 将结束换行符添加到缓冲区中,因此如果最后一个字符是换行符,那么您将获得整行,否则你有“多余”的数据。
  • 你的意思是if (getchar() != '\n') //there is excess data?

标签: c stdin fflush


【解决方案1】:

如果您使用fgets 读取行,并且您担心您可能没有读取整行,请记住如果fgets 读取整行,则换行符应该是输入缓冲区中的最后一个字符.

例子:

char smallBuffer[10];
while (fgets(smallBuffer, sizeof(smallBuffer), stdin) != NULL)
{
    if (strlen(smallBuffer) > 0)
    {
        // Check if we got the whole line
        if (smallBuffer[strlen(smallBuffer) - 1] == '\n')
        {
            // Yes, we got the whole line
        }
        else
        {
            // Whole line not read, there is still "excess" input
        }
    }
}

【讨论】:

    猜你喜欢
    • 2016-05-19
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 2017-10-04
    • 2018-09-18
    • 2017-01-15
    • 1970-01-01
    • 2015-05-14
    相关资源
    最近更新 更多