fgets 不阻塞输入 - C

Posted

技术标签:

【中文标题】fgets 不阻塞输入 - C【英文标题】:fgets not blocking for input - C 【发布时间】:2012-12-29 00:36:09 【问题描述】:

我正在为学校编写程序;这是我第一次使用 C。

我正在使用 fgets 读取输入,但有时 fgets 不会阻塞(将程序抛入无限循环)。要回答每个人的第一个问题,不,我没有使用 scanf 之前留下额外的\n,这会导致这个问题。我曾一度使用 sscanf,但这与 fgets 相关,所以我认为这不是问题。

我们提供了一些处理套接字的代码。我已经浏览了它,但找不到问题的根源。由于篇幅原因,代码没有包含在内,但如果有帮助,我可以包含它。

长话短说,除了 scanf 问题之外,fgets 是否有任何理由不阻止输入?任何帮助表示赞赏!

编辑:我应该在早些时候更清楚地说明这一点,但在这种情况下,我仅将 fgets 用于标准输入。

【问题讨论】:

发布代码更有用...只要 SSCE 你在检查fgets是否返回错误? 阅读fgets 的手册。重读此评论的第一句话。确保在理解后处理 fgets 的返回值。 是的,遇到错误不会阻塞。检查errno中设置的错误码。 啊!谢谢。 fgets 正在返回 nullerrno 设置为 9。有什么想法吗? 【参考方案1】:

与 C 中的大多数标准函数一样,您需要进行一些挖掘才能弄清楚发生了什么。最好的起点是函数文档。

fgets() documentation

从这个文档中,我们可以看到 fgets 接受三个参数并返回一个 char*。假设参数正确,该函数将从流中读取,直到到达换行符或文件末尾标记。在成功的情况下,返回码将是一个指向 str 参数的指针。

不过,您可能更感兴趣的案例是失败案例。失败时,该函数返回 NULL。要确定故障究竟是如何发生的,您需要检查文件错误指示器并查看它是否打印了一条消息。这可以按如下方式完成:

if ( fgets (mystring , 100 , pFile) == NULL )

    // We handle error here
    if (ferror (pFile))
    
        printf ("We encountered an error!\n");
        perror ("Error message");
    

从这里,您应该能够确定发生了什么。可能的原因是参数无效或参数不符合预期的格式/条件。

【讨论】:

感谢您的回复!我进一步研究了它,fgets 返回 null,并且 errno 填充了 9。但仍然不知道为什么会这样...... 快速搜索显示代码 9 通常与 Bad File Descriptor 相关联。这可能意味着fgets() 的第三个参数不正确。也许流尚未初始化或配置?听起来您要么传递了错误的参数,要么传递的参数是正确的,但尚未处于fgets() 可以使用它的状态。 是的,这也是我发现的。不幸的是,它只与标准输入一起使用 你包括<stdio.h>吗? 是的。它在第二次或第三次使用时会中断。我在想一定是有什么东西弄乱了标准输入并使它不可用,但我只是没有足够的 C 经验来知道那可能是什么。【参考方案2】:

我知道这是一个较老的问题,但我想我会分享我遇到此问题时的发现。如果没有您的代码,我无法判断这是否与您遇到的问题相同,但我在自己的代码中发现我在设置为 0 的文件描述符上使用了close()。出于好奇,我查找了文件描述符 0在系统中并且低并且看到 stdin 是 FD 0 (http://en.wikipedia.org/wiki/File_descriptor)。我确信有很多方法可以解决这个问题,但在我的例子中,我使用了一个简单的 if 语句来结束我的关闭:

if(fd > 2)

close(fd);

【讨论】:

以上是关于fgets 不阻塞输入 - C的主要内容,如果未能解决你的问题,请参考以下文章

如何解决fgets读取popen内容阻塞的问题

如何解决fgets读取popen内容阻塞的问题

C 非阻塞键盘输入

Linux下无需按下回车读取输入键值

如何检查stdin是不是仍然打开而不阻塞?

C linux中子进程与父进程之间的通信:父进程不阻塞