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れる場合は、戻り値をチェックして、変換前に入力エラーが発生したかどうかを判断する必要があります。

また、未定義の動作を引き起こすためstdin、フラッシュするべきではないことにも注意してください。fflushフラッシュする必要があると思われる場合は、この質問stdinへの回答を参照してください。

「1,234」などの無効な値が入力された場合、 は「1」scanfを受け入れ、「,234/n」は入力ストリームに残されます。は動作することが保証されていないため、以降の の呼び出しは同じ「,」を何度も何度も拒否し続け、まったく進歩しません。戻り値が 0 であるかどうかがチェックされた場合 (初期のマッチングの失敗を示します)、この無限ループを回避できます。をもう一度呼び出す前に、入力ストリームから無効な文字を削除する必要もあります。fflush(stdin)scanfscanf


無限ループを引き起こす scanf()も参照してください。

于 2010-02-21T04:33:50.470 に答える
1

i > 0かどうかを確認してください。

于 2010-02-20T19:12:29.043 に答える
1

親プロセスが戻った後、制御をシェルに戻します。シェルは自由にそのstdin. stdin有効でアクティブなままであっても、ユーザーは紛らわしいシェル プロンプトを受け取ります。

stdin/out への子のアクセスを保持するには、子が完了するまで親が終了しないようにする必要があります。waitまたは関連する機能を使用します。

#include <sys/wait.h>

…</p>

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

これにより、私のマシンのバグが修正されます。私は Unix ファイル記述子のセマンティクスの専門家ではありませんが、結果として得られるプログラムは移植可能であると思われます。なぜこれをやりたいのかは別問題です…</p>

于 2010-02-21T08:13:10.417 に答える
1

あなたが提供している入力を見ずに言うのは少し難しいです. それがなくても機能する場合fork、アミットが説明したように衝突する可能性があります. ただし、他に 2 つのことがあります。

  1. 使用しないでくださいscanf

  2. fflush(stdin)未定義の動作です。やらないでください。

comp.lang.c FAQ から:

于 2010-02-20T21:15:42.670 に答える
0

最初に、問題を引き起こす最も単純なコードを抽出しようとしました (長い間 C/scanf を使用していませんでした)。のないコードは正常にfork動作します。少しGoogle検索「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 に答える