标准I / O scanf的问题

时间:2015-11-13 07:34:16

标签: c

首先,我只是想说这是来自书中的练习。这是一个非常简单的计算器。该练习专门说使用goto语句使其工作(循环回到开头以输入另一个表达式)。我和本书的作者都知道goto语句通常不是一个好主意。我写过这个小程序,但我无法弄清楚为什么我不能让它工作。

#include <stdio.h>

int main(void)
{
    double num1 = 0.0;                  // first operand value a decimal number
    double num2 = 0.0;                  // second operand value a decimal number
    char oper = 0;                      // operator - must be +, -, *, /, or %
    char again = 0;

    // get the expression from the user
    Start: printf("\n\nEnter the expression: ");
    scanf("%lf %c %lf", &num1, &oper, &num2);

    switch(oper)
    {
        case '+':                       // no checks necessary for addition
            printf(" = %lf\n\n", num1+num2);
            break;
        case '-':                       // no checks necessary for subtraction
            printf(" = %lf\n\n", num1-num2);
            break;
        case '*':                       // no checks necessary for multiplication
            printf(" = %lf\n\n", num1*num2);
            break;
        case '/':
            if(num2 == 0)               // check second operand to see if it's zero
                printf("\n\n\aError:  division by zero!\n\n");
            else
                printf(" = %lf\n", num1/num2);
            break;
        case '%':
            if((long)num2 == 0)         // check second operand to see if it's zero
                printf("\n\n\aError:  division by zero!\n\n");
            else
                printf(" = %ld\n", (long)num1%(long)num2);
            break;
        default:                        // if we get here, it's an illegal operation
            printf("\n\n\aIllegal operation!\n\n");
            break;
    }
    printf("Do you want to perform another calculation?  Y/N: ");
    scanf("%c", &again);
    if((again == 'Y') || (again == 'y'))
    {
        printf("\n");
        goto Start;
    }
    return 0;
}

第一个printf()和scanf()对工作正常。但是,底部的对不起作用(在switch语句下面)。它将printf()函数中的文本打印到屏幕,然后程序结束(我正在使用命令行运行它)。它不允许我输入'Y'使其循环回到开头。如果我删除这两行代码并将它们粘贴在顶部,程序会暂停并等待我的响应就好了(它会让我输入一个响应)。我已经多次来回移动线条,我根本无法弄清楚为什么它在一个地方工作而不是另一个地方。

P.S。我不想使用goto语句,但令我恼火的是,我无法弄清楚为什么我不能从书中得到这个例子。任何帮助,将不胜感激。感谢。

3 个答案:

答案 0 :(得分:3)

您的第一次scanf来电是double,然后是char,然后是double。因此,如果您输入1.00+2.00然后按Enter键,则输入缓冲区stdin将包含:"1.00+2.00\n"scanf族函数的行为是这样的,它只会从输入缓冲区中删除它所读取的内容。在您第一次调用scanf后,stdin缓冲区将包含"\n"

scanf("%c", &again);

正在\n

中读取换行符stdin

将其更改为

scanf(" %c", &again);

按Enter键将始终在输入缓冲区stdin中添加换行符。

如果您想测试scanf()的返回值以覆盖其他输入失败,您可以这样做:

if(scanf(" %c", &again) < 0)
{
printf("Error on scanf!");
}

more info on the nucks and crannys of the scanf function.

答案 1 :(得分:1)

当你使用scanf()时,它从stdin中读取格式化数据,并将剩余的数据留给stdin,以便后续的scanf()调用可以读取它。在您的情况下,第一个scanf()读取数字,并将换行符留给stdin。

下一个scanf()读取一个字符,并且由于stdin中已经有换行符,它会读取换行符并且不会询问您的任何其他输入。

您可以通过连续添加两个getchar()调用,输入两个字符并按Enter键来创建类似的异常。第二个getchar()不会停止并要求您输入,因为stdin中已经有足够的输入。

要解决此问题,您可以更改第一个scanf()调用以包含换行符(这假定用户始终提供有效输入):

scanf("%lf %c %lf\n", &num1, &oper, &num2);

答案 2 :(得分:0)

只需插入getchar,如下所示: N.B:getchar()返回输入缓冲区中的第一个字符,并将其从输入缓冲区中删除

 Start: printf("\n\nEnter the expression: ");
    scanf("%lf %c %lf", &num1, &oper, &num2);
    getchar();//inset this line
// rest of the code will same

需要include<string.h>