1

私はこの問題に直面しています。while ループを使用して数字の文字列をスキャンしており、スキャンを終了してプログラムの残りの部分を開始する必要があります。stdinをフラッシュする方法や、Ctrl + Dを2回押さないようにする方法がわかりません。ループを終了するように伝えるには、EOF を 1 回だけ送信する必要があります。

while (! feof (stdin))
    {status=scanf ("%d", &array[i]);
    if ( (status != 1 && status != EOF) )
    {       printf("\nWrong input.\n");
            return 1;}
    i++;}
4

1 に答える 1

4

編集: glibc のバグ 1190 です。これは明らかに、System V との互換性のために意図的に行われたようです (Solaris は同じように動作し、FreeBSD と NetBSD は期待どおりに動作します)。

あなたの期待は部分的にしか正しくないことに注意してください。

Unix では CTRL-D キーは EOF マーカーではありません。プログラムが入力バッファを読み取れるように、入力バッファをフラッシュします。Unix で EOF と見なされるのは、文字を返さない読み取りであるため、行の先頭で入力バッファーをフラッシュすると、EOF と見なされます。フラッシュされていないデータを入力した後にフラッシュする場合 (自動的に行末フラッシュ入力)、文字を返さず、EOF と見なされる読み取りを行うには、2 回フラッシュする必要があります。

このプログラムを実行すると、次のようになります。

#include <stdio.h>

int main()
{
    int status;
    char tab[200];
    while ((status = fscanf(stdin, "%s", tab)) == 1) { 
        printf("Read %s\n", tab); 
        printf("status=%d\n", status);
        printf("ferror=%d\n", ferror(stdin));
        printf("feof=%d\n", feof(stdin));
    }
    printf("\nOut of loop\nstatus=%d\n", status);
    printf("ferror=%d\n", ferror(stdin));
    printf("feof=%d\n", feof(stdin));
    return 0;
}

行の先頭で CTRL-D を押すと、期待どおりの動作が得られます。

foo
Read foo
status=1
ferror=0
feof=0
^D
Out of loop
status=-1
ferror=0
feof=1

行を終了せずに foo の後に CTRL-D を 2 回押した場合 (上記で説明したように、2 回押すと予想されます)、別の CTRL-D を押す必要があります。

./a.out
foo^D^DRead foo
status=1
ferror=0
feof=1
^D
Out of loop
status=-1
ferror=0
feof=1

これはバグだと思います。 が 1scanfのときに入力すると、EOF の結果ですぐに終了する必要がありましたfeof

于 2013-11-10T13:09:31.610 に答える