11

次のコードは、コンパイルするとすぐに奇妙な o/p を返します。

main() {
    char name[3];
    float price[3];
    int pages[3], i;

    printf ( "\nEnter names, prices and no. of pages of 3 books\n" ) ;

    for ( i = 0 ; i <= 2 ; i++ )
        scanf ("%c %f %d", &name[i], &price[i], &pages[i] );

    printf ( "\nAnd this is what you entered\n" ) ;

    for ( i = 0 ; i <= 2 ; i++ )
        printf ( "%c %f %d\n", name[i], price[i], pages[i] );
}

しかし、scanf ステートメントで %c の前にスペースを入れると、適切な o/p が得られます。

なぜそうなのか、誰か説明してもらえますか?

アップデート:-

このような入力を提供している場合-

F
123.45
56
J
134
67
K
145
98

私の質問は、%f の前にスペースを、%d の前にスペースを与えないのはなぜですか? %c だけの前にスペースを与える必要があるのはなぜですか?

4

2 に答える 2

6

%c を使用した誤った入力

次のコード スニペットを検討してください。

int main( ){
int x;
char y;
scanf("%d", &x);
scanf("%c", &y);
printf("%d %c", x, y);
}

動作:
上記のプログラムを実行すると、10 進数の入力を待機する最初の scanf が呼び出されます。12 を入力するとします (これは ASCII '1' と ASCII '2' です)。次に、「Enter」キーを押して、入力の終わりを知らせます。次に、プログラムは 2 番目の scanf を実行しますが、プログラムは文字の入力を待たずに、すぐに出力 12 に進み、その後に '\n' が続くことに注意してください。



説明:
なぜそれが起こるのですか?プログラムの動作を順を追って見てみましょう。最初はバッファには何もありません。最初の scanf() が呼び出されると、読み取るものがないため、待機します。1,2 を入力してから「Enter」を入力するまで待機し続けます。バッファにあるのは、文字 1、文字 2、および文字 '\n' です。'\n' は、すべてのフィールドが入力されると、入力の終了を意味しますが、ASCII 文字としてバッファにも格納されることに注意してください。この時点で、scanf はバッファーから最大の 10 進入力を読み取り、それを整数に変換します。この例では、文字列 "12" を見つけて 10 進値の 12 に変換し、x に入れます。次に、scanf は制御をメイン関数に戻し、値 1 を返します。1 つのエントリを正常に変換できるため。この例では、変数内の scanf の戻り値をキャッチしません。堅牢なコードの場合、scanf( ) の戻り値をチェックして、ユーザーが正しいデータを入力したことを確認することが重要です。



現在バッファに残っているのは '\n' です。次に、2 番目の scanf が呼び出され、文字が必要です。バッファーには既に '\n' 文字が含まれているため、scanf はそれを認識し、バッファーから取得して y に入れます。そのため、後で printf を実行すると、12 と「enter」が画面に出力されます。



解決策:
ストーリーの教訓は、enter は他の文字と同じであり、バッファーに入力され、他の ASCII 文字と同様に %c によってバッファーから消費されるということです。これを修正するには、代わりに次のコードを使用してみてください。


int main( ){
int x;
char y;
scanf("%d", &x);
scanf("\n%c", &y); /* note the \n !! */
printf("%d %c", x, y);
}


**

これはどのように問題を解決しますか?


** もう一度 '1','2','\n' と入力します。最初の scanf は "1" と "2" を読み取り、それを 10 進数の 12 に変換して、'\n' をバッファに残します。次の scanf は、次の入力の先頭に '\n' を期待するようになりました。バッファ内で '\n' を見つけて読み取り、破棄します。これでバッファは空になり、scanf はユーザーが文字を入力するのを待っています。ユーザーが「c」を入力した後、Enter キーを押したとします。'c' は "enter" ではなく y に割り当てられるようになりました。したがって、printf は "12 c" を画面に出力します。注: '\n' が再びキューに入っています。したがって、単一の文字に対して別の scanf を実行する必要がある場合は、ユーザーから別の文字を取得する前に、その '\n' を「消費」する必要があります。

これは、入力の前の空白をすべて無視するため、他の形式指定子の問題ではありません。

于 2013-06-13T05:57:36.833 に答える