简短版
我想摆脱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)
并不是一个好主意,因为当您将输入流作为参数传递时,它是“未定义的”。
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
然而,同一个来源提到,如果stdin
中没有多余的数据可以摆脱,它将使用用户的下一个输入执行此操作,因此第二次调用fgets
时可能会没有收到所有数据。
如何检查stdin
中是否有数据,以便我可以决定是否清除它?
答案 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
}
}
}