Scanf正在改变我的号码

时间:2014-05-07 04:00:45

标签: c scanf stdio

我有一个程序可以抓取用户输入的数字并添加适当的结尾(第1个,第11个,第312个等) 所以我把它给了我的朋友找到错误/打破它。 代码是

    int number;
    printf("\n\nNumber to end?: ");
    scanf("%d",&number);
    getchar();
    numberEnder(number);

当输入098856854345712355时,scanf将115573475传递给程序的其余部分。 为什么? 115573475小于int的最大值。

3 个答案:

答案 0 :(得分:4)

INT_MAX通常为(2 ^ 31)-1,约为20亿...... ......如果你看98856854345712355 & 0xffffffff,你会发现它是115573475

答案 1 :(得分:3)

C99标准在fscanf部分(7.19.6.2-10)中说明:

  

...转换的结果放在指向的对象中   format参数之后的第一个参数尚未存在   收到了转换结果。如果这个对象没有   适当的类型,或如果转换的结果不能   在对象中表示,行为未定义[强调添加]。

在C11中也是如此,尽管fscanf位于不同的部分(7.21.6.2-10)。

您可以在this excellent answer中阅读有关未定义行为的更多信息,但这基本上意味着标准并不需要任何实现。接下来,你不应该依赖今天scanf使用数字的低位的事实,因为明天它可以使用高位,INT_MAX或其他任何东西。

答案 2 :(得分:2)

098856854345712355对于int来说太大了。

long long number;
printf("\n\nNumber to end?: ");
scanf("%lld",&number);
getchar();
numberEnder(number);

为什么获得特定垃圾回答的答案是GIGO。标准没有指定错误输入的结果,并且它是特定于实现的。如果你对输入应用一个32位掩码,我会猜测,这就是你得到的数字。


出于好奇,我查了scanf的实现。

归结为

…
                                res = strtoq(buf, (char **)NULL, base);
…
                                    *va_arg(ap, long *) = res;
…

哪个应该截断演员阵容中的高位。这将支持位掩码猜测,但这只是这种实现的情况。