2

在这段代码中,scanf只工作一次。我究竟做错了什么?

#include <stdio.h>
#include <unistd.h>

int main()
{
    int i = 1;
    if (! fork())
    {
        while(i)
        {
            printf("Enter i");
            scanf("%d", &i);
            fflush(stdin);
            fflush(stdout);
        }
    }
    else
    {
        printf("Parent\n");
    }
    return(0);
}
4

5 回答 5

3

已经建议您不要使用scanf. 如果您觉得必须使用scanf,则确实应该检查返回值以确定在转换之前是否发生输入错误。

还注意到您不应该通过刷新stdinfflush因为它会调用未定义的行为。如果你觉得你必须同花stdin,你可能想参考这个问题的答案。

如果输入了诸如“1,234”之类的无效值,scanf将接受“1”并且“,234/n”将留在输入流中。由于fflush(stdin)不能保证有效,因此后续调用scanf将一遍又一遍地拒绝相同的“,” ,永远不会取得任何进展。如果检查返回值为零(表示早期匹配失败),则可以避免这种无限循环。在再次调用 之前,还需要从输入流中删除无效字符scanf


参见scanf() 导致无限循环

于 2010-02-21T04:33:50.470 回答
1

如果没有看到您提供的输入,很难说。如果它没有fork那么它可能是阿米特描述的冲突。不过还有两件事:

  1. 不要使用scanf.

  2. fflush(stdin)未定义的行为。不要这样做。

从 comp.lang.c 常见问题解答:

于 2010-02-20T21:15:42.670 回答
1

父进程返回后,它将控制权交还给 shell,shell 可以自由关闭其stdin. 即使stdin仍然有效且处于活动状态,用户也会收到令人困惑的 shell 提示。

要保留孩子对标准输入/输出的访问权限,您需要阻止父母终止,直到孩子完成。使用wait或相关功能。

#include <sys/wait.h>

…</p>

else {
    printf( "parent\n" );
    wait( NULL );
}

这修复了我机器上的错误。我不是 Unix 文件描述符语义方面的专家,但看起来生成的程序可能是可移植的。为什么要这样做是另一回事……</p>

于 2010-02-21T08:13:10.417 回答
1

尝试检查 i > 0。

于 2010-02-20T19:12:29.043 回答
0

首先,我尝试提取最简单的导致问题的代码(很长时间没有使用 C/scanf)。没有工作的代码fork很好。一个小小的谷歌搜索“fork scanf”给了我答案

分叉之后,输入流被关闭。所以 scanf 进入了一个不好的状态。以下程序是对您的程序稍作修改。它打印“流关闭”。

#include<stdio.h>
#include<unistd.h>
int main()
{
        int i = 1;
        if(!fork())
        {
                while(i)
                {
                        printf("Enter i");
                        int j = scanf("%d",&i); // changed
                        if(j == EOF) {             // added
                                printf("stream closed"); // added
                                return 1;       // added
                        }                       // added
                        fflush(stdin);
                        fflush(stdout);
                }
        }
        else
        {
                printf("Parent\n");
        }
        return(0);
}
于 2010-02-20T19:39:05.150 回答