-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 的值,而是直接进入询问 Entering Two no。为什么会这样?

为什么程序会跳过从所需操作的用户那里取值的部分,并进入下一步询问要执行操作的两个编号。为什么程序会跳过该值参与。

4

3 回答 3

4

scanf 可能是有史以来从用户那里获取输入的最不友好的方式。它适用于固定格式的文件(或多或少),但对于交互式输入,我不会用 bargepole 触摸它。

第一个读取数字的 scanf 在第一个非数字处终止,并将其留给下一个 scanf 读取。第一个非数字是您很可能输入的换行符。

这就是你得到的操作。

您最好的选择可能是使用 getline 读取一整行用户输入并在其上使用 sscanf (如果您想稍微验证输入,则使用 strtoul )。

于 2012-09-04T07:26:16.303 回答
3

在第一个之后scanf(),输入缓冲区中剩下一个换行符,由下一个消耗scanf。所以,它不等待输入。

在第一次调用 scanf 后使用getchar()以消耗换行符。

于 2012-09-04T07:25:05.560 回答
3

与标准输入关联的控制台设备通常是行缓冲的,因此 scanf() 直到有完整的行可用时才返回。但是 %d 转换说明符仅消耗数字字符,将换行符(以及您可能键入的任何非数字字符)留在缓冲区中,因此下一个 scanf 调用立即返回但不执行转换。

如果您从未输入任何数字字符而只是按“Enter”,您也会遇到问题。

你应该做两件事:

  1. 检查 scanf() 的返回值以检查有效转换。
  2. 刷新所有剩余字符的行缓冲区,包括换行符

例如:

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 回答