如何在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类型时,如何检查条目数组的第一个条目是不是为空?

如何检查标准输入在 TCL 中是不是可读?

如果没有输入,如何退出代码?代码示例:检查字符串是不是为回文? (在 C 编程语言中)

如何检查标准输入是不是有一些数据?

如何在 iOS 中检查 NSArray 是不是为空或为空?

两个表连接时如何检查字段是不是为空