繁体   English   中英

atoi值的差异

[英]Difference in the values of atoi

我有以下代码:

char* input = (char*)malloc(sizeof(char) * BUFFER) // buffer is defined to 100
int digit = atoi(input); // convert char into a digit
int digit_check = 0;
digit_check += digit % 10; // get last value of digit

当我运行输入1234567896和类似的数字= 1234567896和digit_check = 6。

但是,当我运行输入9999999998时,数字= 141006540​​6,因此当数字应为8时,数字_check = 6。

对于第二个例子,当输入和数字应该是相同的值时,为什么输入和数字之间存在差异?

可能是因为9999999998比最大(带符号)整数表示大,所以你得到溢出。

实际上这是9999999998和141006540​​6的二进制表示:

10  01010100 00001011 11100011 11111110
    01010100 00001011 11100011 11111110

正如您所看到的,如果您看到141006540​​6是32位位值9999999998

atoi仅限于int大小(最近的平台上为32位)。

如果要处理大数字,可以使用atolscanf("%ld")

不要忘记将变量键入long int (或long )。


您也可以只获取输入的最后一个字符(收集为字符串而不是int)并在其上使用atoi ,因此它永远不会溢出。

在许多平台上, int大小限制为4个字节,这限制了[-2 ** 31, 2**31 - 1]

根据您构建的平台,使用strtol (或strtolllong (或long long )。 例如,x86上的GCC将具有64位long long ,而对于amd64,它将具有64位longlong long型。

所以:

long long digit = strtoll(input, NULL, 10);

注意: strtoll()在类Unix系统中很流行,并且在C ++ 11中成为标准,但并非所有VC ++实现都有它。 使用_strtoi64()代替:

__int64 digit = _strtoi64(input, NULL, 10);

你可能想使用atoll函数返回一个long long int ,也就是两倍大int (最有可能在你的情况下,64位)。

它在stdlib.h声明

http://linux.die.net/man/3/atoll

你应该避免在未初始化的字符串上调用atoi ,如果字符串上没有\\0 ,你将无效读取并出现分段错误。 你应该使用strtoimax ,它更安全。

9999999998大于整数可以表示的最大值。 要么使用atol() OR atoll()

您应该停止使用atoi功能或来自ato...组的任何其他功能。 这些功能尚未正式弃用,但自1995年以来就被有效放弃,仅用于遗留代码兼容性目的。 忘记这些功能就好像它们不存在一样。 这些功能在出现错误或溢出时不提供有用的反馈。 溢出就是你的例子中明显发生的事情。

为了将字符串转换为数字,C标准库提供strtol函数和strto... group的其他函数。 这些是您应该用于执行转换的函数。 并且不要忘记检查溢出的结果: strto...函数通过返回值和errno变量提供此反馈。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM