如何检查以确保在调用atoi()之前有一个整数?

时间:2010-10-03 16:23:26

标签: c casting atoi

我希望将整数作为命令行参数,但如果用户传递非整数字符串,则会导致堆栈溢出。确保atoi()成功的标准方法是什么?

9 个答案:

答案 0 :(得分:21)

您可以使用:

long int strtol(const char *nptr, char **endptr, int base);

然后检查是否*endptr != nptr。这意味着字符串至少以整数开头。 您还可以检查* endptr指向终止为零,这意味着整个字符串已成功解析。

答案 1 :(得分:5)

如果字符串包含除数字以外的字符,

atoi()将(不应)导致堆栈溢出。它将简单地转换为从字符串开头找到的int任何数字,直到不再存在为止。

  int x = atoi("12monkeys"); // x is 12
  int y = atoi("monkeys12"); // y is 0

您可以检查在现代(当前)PC架构上没有整数溢出(数字超出[-2 ^ 31,2 ^ 31-1]范围)。

修改(评论)

如果C标准警告未定义的行为,如果无法表示该值,则最常见的C最近编译器(gcc,MS ...)不会崩溃如果该值不可接受(除非char *指针当然为空或错误。)

无论如何,您可以轻松实现自己的atoi()(与我的回答中的限制相同)

    #include <ctype.h>

    int myatoi(char *s) {
       int res = 0, minus = *s == '-';
       if (minus) s++;

       while (isdigit(*s)) {
          res = res*10 + (*s++ - '0');
       }

       return minus ? -res : res;
    }

答案 2 :(得分:1)

这不会导致堆栈溢出。 atoi如果在字符串的开头找不到数字,则返回0。您(非)处理0是导致堆栈溢出的原因。

答案 3 :(得分:1)

导致堆栈溢出?好吧,如果字符串中的值超出int的范围,我认为这是未定义行为的一种可能结果。在实践中,它通常只是包装或返回虚假结果。

如果您想要更好的错误检查,请使用strtol代替atoi。它在溢出时具有明确定义的行为(它设置errno,在调用strtol之前需要将其清除为0,以便区分错误返回和返回的合法值)并且可以检查点在它停止转换的字符串中,查看完整字符串是否为整数,或者是否有超出结尾的其他内容。

答案 4 :(得分:0)

我认为标准atoi不会堆栈溢出,但是没有办法判断你是否没有整数。使用strtol代替 - 可以处理非整数。

http://en.wikipedia.org/wiki/Strtol

答案 5 :(得分:0)

这可能会对你有所帮助。检查stdlib.h中的strtol

答案 6 :(得分:0)

你可以这样做并输入Undefined Behavior land,你可以编写一个简单的验证函数,如下所示:

/* returns 0 on success, 1 on failure. */

int verify(char * string)
{
    int x = 0;
    int len = strlen(string);

    while(x < len) {
           if(!isdigit(*(string+x)))
           return 1;

           ++x;
    }

    return 0;
}

请注意,在调用atoi()之前必须先调用此函数,并且需要string.h和stdio.h。

答案 7 :(得分:0)

atoi()如果只包含数字字符,则将字符串转换为整数,否则返回0.

答案 8 :(得分:0)

要检查溢出,您可以简单地将您从 atoi 获得的数字转换回字符串。现在将此字符串与您的输入字符串进行比较。如果它们匹配,则不是溢出,否则是。

在此处查看伪代码:

int check_overflow(int num, char *arr, int len){
    char buf[len + 1];
    sprintf(buf, "%d", num);
    if(strcmp(buf, arr) == 0){
            return 0;
    }
    return -1;
}

如果溢出则函数返回-1,否则返回0。