当我们使用%d扫描一个角色时会发生什么?

时间:2017-03-06 11:30:49

标签: c

我运行了这段代码

#include <stdio.h>
int main()
{
    int u;
    scanf("%d",&u);
    printf("%d\n",u,u);
    return 0;   
}

以下是输入和输出:

input:a output:32765
input:b output:32765
input:c output:32767
input:/ output:32766

任何人都可以解释这种行为吗?

2 个答案:

答案 0 :(得分:2)

程序的行为是未定义

您应该检查scanf的返回值,它会告诉您读入传递参数的数据的数量。在您的情况下,返回值将为零,因为%d不能用于读取char。因此u未初始化,因此不应读取其值。

请注意,您已将多余参数传递给printf这一事实是良性的,尽管正式地仍然会评估此类参数。请参阅Is calling printf with excess arguments undefined behaviour?

故事的寓意:始终检查scanf的返回值。

答案 1 :(得分:2)

scanf()读取输入时,它无法根据规范进行转换,它会停止扫描并返回成功转换的次数。在您的情况下,字符保留在标准输入缓冲区中,scanf()返回0

您的代码具有未定义的行为,因为scanf()无法将输入转换为整数,而u未初始化。将此未初始化的值传递给printf具有未定义的行为。在您的情况下,打印一个稍微随机的值,可能会有所不同或不同,但任何其他行为都可能包括崩溃。

您必须测试scanf()的返回值,以检查转换是否成功。这是一个修改版本:

#include <stdio.h>

int main(void) {
    int u, res;
    res = scanf("%d", &u);
    if (res == 1) {
        /* conversion succeeded */
        printf("%d\n", u);
    } else
    if (res == 0) {
        /* conversion failed */
        printf("input is not a valid number\n");
    } else {
        /* res must be EOF */
        printf("premature end of file: no input given\n");
    }
    return 0;   
}