当scanf输入是一个字符但转换说明符和变量是整数时,打印整数变量会返回“怪异”数字。为什么?

时间:2016-02-09 08:48:42

标签: c scanf

我已经阅读了类似的C ++代码问题和答案,只是想确认我的理解。

对于下面的C代码;

#include <stdio.h>

int main(void){

    int a, b, c, d; 
    a = scanf("%d%d%d", &b, &c, &d); 
    printf("Number of values read: %d\n", a); 
    printf("Values read: %d %d %d", b, c, d); 

return 0;
}

如果输入为0 A 0

我的输出是;

Number of values read: 1
Values read: 0 0 4200544

以下说明是否正确? scanf期望数据类型int,但获取char作为输入。因此,它停止读取并返回值0.

仅准确地给出了1个值作为输入,因此读取的值的数量为:1

第二个int被赋值为0.最后一个int var是未分配的,因此在打印时,它会返回垃圾值。

有更好的解释吗?我只是想确保我对输出的原因有正确的理解。

4 个答案:

答案 0 :(得分:3)

scanf转换失败时,相应的输出变量以及之后的所有变量都保持不变。因此,示例输入0 A 0b设置为0,但不会更改cd的值。由于cd未初始化,因此将其值传递给printf会导致未定义的行为c打印为0只是巧合。

更好的测试是在调用scanf之前将所有变量初始化为已知值,例如

int main(void){

    int a = 101, b = 102, c = 103, d = 104;
    a = scanf("%d%d%d", &b, &c, &d);
    printf("Number of values read: %d\n", a);
    printf("Values read: %d %d %d\n", b, c, d);

    return 0;
}

此外,对测试输入使用非零值是个好主意(因为0往往是未初始化变量的常见结果),例如如果输入为5 A 7,则输出为

Number of values read: 1
Values read: 5 103 104

清楚地显示ab已更改,但cd未更改。

答案 1 :(得分:1)

  

仅准确地给出了1个值作为输入,因此读取的值的数量为:1

正确!

  

第二个int被赋值为0.最后一个int var是未分配的,因此在打印时,它会返回垃圾值。

错误 - 因为您的第二个输入(c)与控制字符串d不匹配,所以A%d都不会读取任何内容,因此这些值的值是都是un-itialized / garbage。您可以在c之前和之后打印dscanf来证明:

int a, b, c, d;   // 
printf("Initial values: %d %d\n", c, d);  // <-- c, d are garbage from here (1)
a = scanf("%d%d%d", &b, &c, &d);   // <-- scanf does not change `c` and `d` here because 2nd input is of wrong format 
printf("Number of values read: %d\n", a); 
printf("Values read: %d %d %d\n", b, c, d);   // <-- c, d remain garbage here (2). No guarantee but chances are the same as (1)

警告:上述代码表明您的scanf实际上对cd没有影响。在 all 的情况下,您应该在使用前始终初始化变量。

int a = 1, b = 2, c = 3, d = 4;     // <-- always initialize before use (CORRECT CODE)
printf("Initial values: %d %d\n", c, d);    // <-- c = 3, d = 4
a = scanf("%d%d%d", &b, &c, &d);    // <-- scanf does not change `c` and `d` here because 2nd input is of wrong format 
printf("Number of values read: %d\n", a); 
printf("Values read: %d %d %d\n", b, c, d);    // <-- c = 3, d = 4

答案 2 :(得分:0)

输出未初始化的变量会导致undefined behaviour。这意味着可能发生任何事情尝试理解确切的输出没有多少理由,因为它可能会随着帽子的变化而变化。整个程序行为是未定义的,你甚至不能依赖第一个输出或类似的东西。

任何&#34;解释&#34;你通过试验推断系统可能不适用于其他系统或其他编译器,或者你改变了编译器设置,甚至完全随机波动。

答案 3 :(得分:0)

除了未初始化的变量之外,您使用的scanf使用了错误的scanf类型说明符,即对于变量c,您提供了一个字符并尝试将其保存为十进制整数。如果您打算阅读字符,则可以定义char类型的变量,并且更好scanf行:

scanf("%c%c%c", &b, &c, &d);

之后,您可以使用%d说明符打印它们,将它们视为整数,这样您就可以看到它们的数字表示形式,例如:

printf("Values read: %d %d %d", b, c, d);

如果您愿意,也可以在代码中进行char转换为int。有关scanf的类型说明符的更多信息是here

同样,这与您使用单元化变量的事实不同,其他答案解释得非常好。