【发布时间】: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?