【问题标题】:Calling fgets() twice causes second call to not complete两次调用 fgets() 会导致第二次调用未完成
【发布时间】:2013-03-21 21:33:44
【问题描述】:

我已经在谷歌上搜索了几个小时,但到目前为止我还没有看到任何提及它。

int getInt()
{
    char* rawin = (char*)malloc(100);
    printf("How big should the secret code be?\n(Input number of elements):\n");

    while(fgets(rawin, 100, stdin) != NULL)
    {
        if (sscanf(rawin,"%d") == 1)
        {
          break;
        }
        printf("Numbers only please.\n");
    }
    int in = atoi(rawin);
    free(rawin);
    return in;
}

如果我调用这个函数两次,无论我第一次调用哪个都可以正常工作,但第二个会表现得很奇怪。程序没有进入 while 循环,而是像在 fgets 上无限循环一样。 fgets 的第二次调用永远不会完成,因此永远不会返回任何内容。调试时,永远不会到达“while(fgets...”之后的任何位置,包括循环之后的断点。我尝试将“\n”、“\0”和“\n\0”附加到标准输入的末尾,它什么也没做。我尝试通过读出每个不是“\n”或\0'的字符来“刷新”标准输入,但它也什么也没做。

编辑:澄清一下,“if”语句中的条件是占位符。

【问题讨论】:

  • for 代表什么?
  • 您确定有足够的输入供第二轮循环读取吗?如果stdin 上的缓冲区为空,fgets 将阻塞。输入来自哪里?如果你的第一次迭代从来没有你的中断条件,那么第一个 while 循环将一直读取到EOF,第二个循环将无限期阻塞,除非发送输入的任何东西决定恢复管道并发送更多数据。
  • @HalimQarroum:那应该是一个占位符。会修复的。
  • fgets 返回一个指针,而不是一个整数。针对 NULL 进行测试。
  • 您能否提供一个小的工作示例,其中包含两个复制它的函数调用?

标签: c fgets


【解决方案1】:

您需要将数据存储在某个地方:

if (sscanf(rawin,"%d") == 1)

也就是说,您的sscanf() 需要第三个参数:指向要存储此转换结果的整数的指针:

int in;
if (sscanf(rawin,"%d",&in) == 1)

此后您无需致电atoi()


附带说明,在您的示例中不需要动态分配内存。一个简单的数组就足够了:

char rawin[100];

【讨论】:

  • @CybeatB 很高兴我能帮上忙。下一次包括所有您的代码,或者至少是重现错误的最小数量。在您从之前的帖子中删除混淆之前,尚不清楚发生了什么。
【解决方案2】:

尝试使标准输入非阻塞。

#include <unistd.h>
#include <fcntl.h>

fcntl(0, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK);

或者使用非阻塞 recv 代替 fgets:

#include <sys/socket.h>

while(recv(0, inputString, 100, MSG_DONTWAIT) > 0)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多