我有一个程序可以抓取用户输入的数字并添加适当的结尾(第1个,第11个,第312个等) 所以我把它给了我的朋友找到错误/打破它。 代码是
int number;
printf("\n\nNumber to end?: ");
scanf("%d",&number);
getchar();
numberEnder(number);
当输入098856854345712355时,scanf将115573475传递给程序的其余部分。 为什么? 115573475小于int的最大值。
答案 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;
…
哪个应该截断演员阵容中的高位。这将支持位掩码猜测,但这只是这种实现的情况。