-3
#include <stdio.h>

int main()
{
    int c1;
    char op;
    printf("\n(Int or Float) \n\t[1.for int  2.for float] \nEnter Choise : ");
    scanf("%d",&c1);

    if (c1==1)
    {
        printf("\n(select opearion) \n\t[+, -, *] \nEnter Choise : ");
        scanf("%c", &op);

        int a,b,r;
        printf("\n Enter Two no. : ");
        scanf("%d%d ", &a,&b);

        switch (op)
        { 
        case '+': r=a+b;
            break;
        case '-': r=a-b;
            break;
        case '*': r=a*b;
            break;
        default:
            printf("Wrong Operator Entered");   
        }
        printf("\n\n Result = %d \n\n",r);
    }
    else if(c1==2)
    {
        printf("\n(select opearion) \n\t[+, -, *] \nEnter Choise : ");
        scanf("%c", &op);

        float a,b,r;
        printf("\n Enter two numbers : ");
        scanf("%f%f", &a,&b);

        switch (op)
        { 
        case '+': r=a+b;
            break;
        case '-': r=a-b;
            break;
        case '*': r=a*b;
            break;
        default:
            printf("Wrong Operator Entered");   
        }
        printf("\n\n Result = %f\n\n",r);
    }
    else
    {
        printf("\n\n Wrong choise entered \n\n");
    }
}

このプログラムを実行すると、プログラムはopの値を取得するのを待たずに、直接2つの入力を要求します。なぜこれが起こるのですか?

プログラムが目的の操作のユーザーから値を取得する部分をスキップし、操作を実行する2つの番号を要求する次のステップに進むのはなぜですか。プログラムが参加しているその値をスキップするのはなぜですか。

4

3 に答える 3

4

scanf はおそらく、ユーザーからの入力を取得する最もユーザーフレンドリーな方法ではありません。固定形式のファイルでは(多かれ少なかれ)問題なく動作しますが、インタラクティブな入力の場合は、バージポールで触れません。

数値を読み取る最初の scanf は、最初の非数字で終了し、次の scanf が読み取るためにそれを残します。最初の非数字は、おそらく入力した改行です。

そして、それがあなたがopのために得るものです。

あなたの最善の策は、おそらく getline を使用してユーザー入力の行全体を読み取り、その上で sscanf を使用することです (または、入力を少し検証したい場合は strtoul を使用します)。

于 2012-09-04T07:26:16.303 に答える
3

stdin に関連付けられたコンソール デバイスは通常、ライン バッファリングされているため、完全なラインが使用可能になるまで scanf() は戻りません。ただし、%d 変換指定子は、バッファ内の改行(および入力する可能性のある非数字文字) を残して数字文字のみを消費するため、次の scanf 呼び出しはすぐに返されますが、変換は実行されません。

また、数字を入力せずに「Enter」を押した場合にも問題が発生します。

次の 2 つのことを行う必要があります。

  1. scanf() の戻り値をチェックして、有効な変換をチェックします。
  2. newline までの残りのすべての文字のライン バッファーをフラッシュします

例えば:

int scanf_check ;

...

// Accept valid input
do
{
    scanf_check = scanf("%d",&c1);

} while( scanf_check != 0 )

while( getchar() != '\n' ) { /* do nothing */ } // Flush the line

%ca を使用する場合は、少し異なるイディオムが必要です。%c ですべての文字を読み取ることができるため、変換チェックは不要ですが、入力 ID が「空」の場合でも改行が存在するため、次のようになります。

scanf("%c", &op);
while( op != '\n' && getchar() != '\n' ) { /* do nothing */ } // Flush the line

op がすでにnewlineである場合、 && の短絡評価が行われ、getchar() は呼び出されません。それ以外の場合は、入力の終わりが見つかるまで以前と同様に getchar() が呼び出されます。

于 2012-09-04T07:34:41.110 に答える