C atoi值的差异
我有以下代码:C atoi值的差异,c,C,我有以下代码: 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时,同样的数字=123456789
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和数字检查=6
但是,当我运行输入99999998 8时,digit=1410065406,因此digit_check=6,此时它应该是8
对于第二个示例,当输入和数字应该是相同的值时,为什么输入和数字之间存在差异?
atoi
被限制为int大小(在最新的平台上为32位)
如果要处理大的数字,可以使用atol
或scanf(“%ld”)
不要忘记将变量键入long int
(或long
)
您也可以只获取输入的最后一个字符(收集为字符串而不是整数),并在其上使用
atoi
,这样它就不会溢出。可能是因为99999998大于最大(有符号)整数表示,所以您会得到溢出
实际上,这是999999998和1410065406的二进制表示:
10 01010100 00001011 11100011 11111110
01010100 00001011 11100011 11111110
如您所见,如果您看到1410065406是99999998的32ed位值,在许多平台上,
int
的大小限制为4个字节,这限制了[-2**31,2**31-1]
中的数字
根据您构建的平台,将long
(或long
)与strtol
(或strtoll
)一起使用。例如,x86上的GCC将具有64位long
,而对于amd64,它将具有64位long
和long
类型
因此:
注意:strtoll()
在类Unix系统中很流行,并在C++11中成为标准,但并非所有VC++实现都有它。请改用\u stroi64()
:
__int64 digit = _strtoi64(input, NULL, 10);
您可能希望使用
atol
函数,该函数返回一个long-long-int
,该值是int
的两倍(在您的情况下最有可能是64位)
它在stdlib.h
您应该避免对未初始化的字符串调用
atoi
,如果该字符串上没有\0
,则会导致读取无效并出现分段错误。
您应该使用strotimax,因为它更安全。99999999 8大于整数可以表示的最大值。使用
atol()
或atol()
您应该停止使用atoi
函数或ato…
组中的任何其他函数。这些函数并没有被正式弃用,但自1995年以来,它们实际上已被放弃,并且只存在于遗留代码兼容性目的。忘记这些函数,就好像它们不存在一样。这些函数在发生错误或溢出时不提供可用的反馈。在你的例子中,溢出是很明显发生的
为了将字符串转换为数字,C标准库提供了
strtol
函数和strto…
组中的其他函数。这些是执行转换时应使用的函数。不要忘了检查溢出结果:strto…
函数通过返回值和errno
变量提供此反馈。您需要计算一个int可以存储在您的平台上的最大值。@nos刚刚了解了它,谢谢。sizeof(char)定义为1。您可以安全地使用“malloc(缓冲区)”。在C中,您还可以避免强制转换malloc()的返回值。除了@Jack的注释外,如果BUFFER
(其中BUFFER\u SIZE
是一个更好的名称)是#define
d到100(编译时常量),您可以通过完全避免动态内存分配来简化程序,只需要一个char缓冲区[BUFFER_SIZE];
。最大值为有符号32位整数(使用2的补码)“您可以保留的电话号码是2147483647。@blue112谢谢您提供的快速易懂的答案,我们会尽快将其标记为已回答。”me@5gon12eder:严格来说,有符号整数类型的正子范围的属性不依赖于有符号表示,即“2的补码”与此无关。@AnT True适用于1的补码、2的补码、符号大小和对称偏差表示。理论上,您可以定义一种奇怪的数字格式,其中正范围不同,但我不确定C标准是否允许,而且我非常确定没有实现使用它。
__int64 digit = _strtoi64(input, NULL, 10);