scanf功能可以使用多少次?

时间:2013-12-17 19:22:41

标签: c io scanf

为了回到C编程的流程,我一直在打字一些简单的测试程序。我遇到了scanf函数的一个奇怪问题。我在下面的代码中有3个,但只有前2个被初始化;第三个scanf被忽略。这是正常的,还是我做错了什么?我一直在盯着这段代码过去半小时,我找不到任何错误。

#include <stdio.h>

int math(int a, int b, char selection) {

    int result;

    switch (selection) {
        case 'a':
        result = a + b;
        break;
        case 's':
        result = a - b;
        break;
        case 'm':
        result = a * b;
        break;
        case 'd':
        result = a / b;
        break;
    }

    return result;
}

int main() {
    int num1 = 0;
    int num2 = 0;
    int result = 0;
    char selection;

    printf("Enter first number: ");
    scanf("%i", &num1);

    printf("Enter second number: ");
    scanf("%i", &num2);

    printf("\n[a] Add\n[s] Subtract\n[m] Multiply\n[d] Divide\n\nWhich one: ");
    scanf("%c", &selection);

    result = math(num1, num2, selection);
    printf("%i", result);

    return 0;
}

1 个答案:

答案 0 :(得分:7)

回答你的问题:
scanf功能可以使用多少次?

不,没有。

但这不是这里发生的事情。

当你做这样的事情时:

printf("Enter second number: ");
scanf("%i", &num2);

您实际上在stdin上输入了两个值,第一个是数字,第二个是不可见的换行符。

                     you can't see that, but it's there
                         V
> Enter second number: 3\n    

scanf()的工作方式,它会将stdin的输入读取并存储到您的变量中,直到它们全部填满,然后它将完成剩下的工作。在我的示例3已存储到num2,而'\n'保留在stdin然后当此代码运行时:

scanf("%c", &selection);

它将在stdin上查找并找到位于那里的换行符('\n')。这可以存储为字符类型,因此它将填充selection

解决此问题的一种方法是将代码更改为:

scanf(" %c", &selection);

%之前的空格告诉scanf忽略位于stdin缓冲区开头的任何空格(包括换行符)。


关于调试的附注:

当您认为出现问题时,请使用调试器或打印一些值以给您信心和理解。例如,我会更新您的代码:

printf("\n[a] Add\n[s] Subtract\n[m] Multiply\n[d] Divide\n\nWhich one: ");
int ret = scanf("%c", &selection);

printf("Scanf I think failed. Return value is: %d. Selection is: %c (%d)\n", 
        ret, selection, selection);

您可以从手册页中找到返回值的含义。在this case中,此处的返回代码将告诉您已成功匹配和分配了多少项。你在这里看到1,所以你知道这个电话有效。您的输出将如下所示:

Scanf I think failed. Return value is: 1. Selection is:
(10)

这告诉你scanf确实得到某些东西,你没有看到打印的字符,但输出跳过一行(可疑)和ASCII值打印的是10 10 ,看起来你会看到它是换行符。