这两个函数有什么区别,后者不考虑参数中的所有字符串,而第一个函数考虑

问题描述 投票:0回答:2

我写了一个函数,意思是像

<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
)之后的所有内容的两个代码之间有什么区别?

c function arguments atoi
2个回答
0
投票

第一个代码的循环条件是

s[i] != '\0'
。这意味着循环将一直运行到字符串末尾,而不管之前是否存在未转换的字符。

另一方面,第二个代码中最后一个循环的循环条件是

s[i] <= '9' && s[i] >= '0' && s[i] != '\0'
。这将使循环在第一个不是数字的字符处停止。

因此,第一个代码将在

94111 -
之后的非数字字符后看到
98
,而第二个代码则不会。


0
投票

第一个函数迭代整个字符串,将存在的所有数字组合成一个数字,即使它们被其他字符分隔。它还将任何出现的

-
解释为应用于结果数字的负号。这绝对不是
atoi()
的行为。

第二个函数首先跳过任何非数字,只测试

-
符号被解释为改变结果的符号。然后它迭代数字,直到找到非数字或字符串的末尾。因此它只解释字符串中出现的第一个数字,可能多次否定它。这会为您的输入字符串产生不同的值,但仍然不是
atoi()
.

的行为

标准函数

atoi
首先跳过任何空白字符(由
isspace()
定义,然后接受一个可选符号(单个
+
-
字符),然后解析任何紧随其后的数字并停止在第一个非数字。对于测试字符串,它返回
0
.

建议在

strtol()
上使用
atoi()
以避免在包含超出类型
int
范围的整数表示的字符串上出现未定义的行为。

这里是

atoi()
的简单实现,具有定义的行为:

#include <limits.h>
#include <stdlib.h>

int atoi(const char *s) {
    long n = strtol(s, NULL, 10);
    return n < INT_MIN ? INT_MIN :
           n > INT_MAX : INT_MAX : n;
}

如果不使用

<stdlib.h>
就想实现自己的功能,可以使用:

#include <ctype.h>
#include <limits.h>

int my_atoi(const char *s) {
    int res = 0;

    while (isspace((unsigned char)*s)) {
        s++;
    }
    if (*s == '-') {
        s++;
        while (*s >= '0' && *s <= '9') {
            int digit = *s++ - '0';
            if (res < INT_MIN / 10
            ||  res == INT_MIN / 10 && -digit < INT_MIN % 10) {
                res = INT_MIN;
            } else {
                res = res * 10 - digit;
            }
        }
    } else {
        if (*s == '+') {
            s++;
        }
        while (*s >= '0' && *s <= '9') {
            int digit = *s++ - '0';
            if (res > INT_MAX / 10
            ||  res == INT_MAX / 10 && digit > INT_MAX % 10) {
                res = INT_MAX;
            } else {
                res = res * 10 + digit;
            }
        }
    }
    return res;
}
© www.soinside.com 2019 - 2024. All rights reserved.