Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C atoi值的差异_C - Fatal编程技术网

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);