如何在C中检查stdin是不是为空
Posted
技术标签:
【中文标题】如何在C中检查stdin是不是为空【英文标题】:How to check if stdin is empty in C如何在C中检查stdin是否为空 【发布时间】:2013-12-16 10:51:23 【问题描述】:我正在(重新)学习 C 编程,所以以下问题是为了便于理解。 使用 scanf() 我了解到(或者我自己发现,到这一点并不需要很长时间)刷新标准输入是一件好事。我进一步发现(在你的帮助下) fflush(stdin) 不是标准的事情,例如不适用于 gcc。 我继续使用下面的代码 sn-p 来刷新标准输入。它是在这里提供的(谢谢)。如果标准输入不为空,它工作正常。但是,如果 stdin 为空,则它不起作用。我的刷新函数中的 fgetc() 只是等待并阻止程序。事实上,到目前为止我所知道的所有其他标准输入读取函数(scanf()、fgetc()、gets()、fgets()、getchar())都表现出相同的行为。所以我的刷新函数实际上是一个条件刷新:它只有在缓冲区不为空时才会刷新。如果它是空的,则刷新会阻塞程序并等待标准输入的输入。这不是我想要的。所以,我需要的是一种检查标准输入是否为空的方法。如果是我继续。如果不是,我运行我的冲洗功能。
所以,我正在寻找的是一种检查标准输入是否为空的 C 标准方法。
非常感谢您的帮助!
void flush_line(FILE *);
/* function to flush stdin in a C standard way since*/
/* fflush(stdin) has undefined behaviour. */
/* s. http://***.com/questions/20081062/fflushstdin-does-not-work-compiled-with-gcc-in-cygwin-but-does-compiled-with-v */
void flush_line(FILE *fin)
int ch;
do
ch = fgetc(fin);
while (ch != '\n' && ch != EOF);
【问题讨论】:
不幸的是,这可能效果不佳,因为如果没有要读取的字符,fgetc
会阻塞。
“刷新”输入流到底是什么意思?
冲洗我的意思是清空输入流,以确保那里没有不应该的东西,例如在要求用户输入并从标准输入读取此输入之前。
@CharlesBailey 可能是consuming
里面的所有剩余数据...
哦,如果fin
是一个文件(而不是stdin
),那么您无法知道实现是否继续连续缓冲,因此缓冲区可能永远不会清空。
【参考方案1】:
不要将stdin
视为数据可用或不可用的地方。它被称为 stream 的原因是:您总是对其中的 next 数据感兴趣,只要有可用的数据。
具体而言,您出于原因决定“冲洗”(也许“排水”是一个更好的词)流。也许您向用户请求了一个整数,而他们输入了字母。那么,您知道,流不是“空的”,因为其中有字母!所以阅读到下一个换行符是一个合理的想法。
或者也许(为了与其他一些实用程序兼容?)您有一个协议,其中某行输入是不相关的。然后你可以“排干”那条线;用户是否输入了任何内容都没有关系,因为您必须等到他们输入之后才能接受他们的更多输入。
【讨论】:
【参考方案2】:我以 cancerous 的方式解决了这个问题,但效果很好。如果仅在标准输入脏(非空)时有效,那么只需在清除它之前始终向标准输入发送\n
。是的,我知道,这似乎是一个非常丑陋的解决方案,但这是我认为可移植的唯一明智的方式,因为 select 或 poll 不适用于 Windows)。
这里是:
void flush_stdin()
char c;
ungetc('\n', stdin); // ensure that stdin is always dirty
while(((c = getchar()) != '\n') && (c != EOF));
【讨论】:
现在 while 循环立即停止,因为您获取了它正在搜索的 '\n'。【参考方案3】:您可以使用 select 或 poll 来检查文件描述符是否可读。但不在 ANSI C 中。
【讨论】:
以上是关于如何在C中检查stdin是不是为空的主要内容,如果未能解决你的问题,请参考以下文章
当数组是C中的struct类型时,如何检查条目数组的第一个条目是不是为空?