C:Stdin - 删除多余数据

时间:2014-08-27 12:10:27

标签: c stdin fflush

简短版

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

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

我在CProgramming.com

上找到了这个替代品
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);

然而,同一个来源提到,如果stdin中没有多余的数据可以摆脱,它将使用用户的下一个输入执行此操作,因此第二次调用fgets时可能会没有收到所有数据。

如何检查stdin中是否有数据,以便我可以决定是否清除它?

1 个答案:

答案 0 :(得分:2)

如果您使用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
        }
    }
}