我写了一个函数,其作用类似于<stdlib.h>
函数atoi
:
int _atoi(char *s)
{
int i, neg = 1, n = 0;
for (i = 0; s[i] != '\0'; i++)
{
if ((s[i] >= '0') && (s[i] <= '9'))
n = n * 10 + (s[i] - '0');
else if (s[i] == '-')
neg *= -1;
}
n *= neg;
return (n);
}
当我运行它的时候
nb = _atoi(" + + - -98 Battery Street; San Francisco, CA 94111 - USA ");
printf("%d\n", nb);
输出为-9894111
但是使用类似的代码,例如:
int _atoi(char *s)
{
int sign = 1, i = 0, res = 0;
while (!(s[i] <= '9' && s[i] >= '0') && s[i] != '\0')
{
if (s[i] == '-')
sign *= -1;
i++;
}
while (s[i] <= '9' && s[i] >= '0' && s[i] != '\0')
{
res = (res * 10) + (s[i] - '0');
i++;
}
res *= sign;
return (res);
}
输出为98
,这是真实的atoi
函数返回的结果。
这两个代码之间的区别是什么,会使后者忽略8
之后的所有内容(即-
和94111
)?
2条答案
按热度按时间jvlzgdj91#
第一个函数对整个字符串进行迭代,将所有出现的数字组合成一个数字,即使这些数字被其他字符分隔,它也将任何出现的
-
解释为负号,以应用于结果数字,这绝对不是atoi()
的行为。第二个函数首先跳过任何非数字,只测试被解释为改变结果符号的
-
符号。然后,它迭代数字,直到找到一个非数字或字符串的结尾。因此,它只解释字符串中出现的第一个数字,并可能对其求反多次。这将为您的输入字符串生成一个不同的值。但仍然不是atoi()
的行为。标准函数
atoi
首先跳过任何白色字符(由isspace()
定义),然后接受可选符号(单个+
或-
字符),然后解析任何紧跟其后的数字并在第一个非数字处停止。对于测试字符串,它返回0
。建议使用
strtol()
而不是atoi()
,以避免在包含超出int
类型范围的整数表示形式的字符串上出现未定义的行为。下面是
atoi()
的一个简单实现,其中定义了行为:如果您想在不使用
<stdlib.h>
的情况下实现自己的函数,可以用途:pvcm50d12#
第一个代码的循环条件是
s[i] != '\0'
,这意味着循环将一直运行到字符串末尾,而不管在此之前是否存在未转换的字符。另一方面,第二个代码中最后一个循环的循环条件是
s[i] <= '9' && s[i] >= '0' && s[i] != '\0'
,这将使循环在第一个不是数字的字符处停止。因此,第一个代码将在
98
之后的非数字字符之后看到94111 -
,而第二个代码则不会。