atoi - 如何识别零和错误之间的区别?

时间:2012-01-15 17:25:18

标签: c

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

返回值

成功时,该函数将转换后的整数作为int值返回。 如果无法执行有效转换,则返回零值。 如果正确的值超出可表示值的范围,则返回INT_MAX或INT_MIN。

所以我在atoi("poop")atoi("0")以及atoi("0000000")

之间的区别如何

是的,我可以循环并检查所有零,以防我得到0结果,但是没有更好的方法吗?

注意:我使用的是ANSI C89

4 个答案:

答案 0 :(得分:35)

这是atoi有时被认为不安全的原因之一。请改用strtol / strtoul。如果你使用strtonum

函数atoi比你想象的更危险。 The POSIX standard说:

  

如果无法表示该值,则行为未定义。

C99标准也说明了这一点:

  

7.20.1

     

atof,atoi,atol和atoll的功能不需要影响它的价值   错误的整数表达式errno。如果是结果的值   无法表示,行为未定。

答案 1 :(得分:13)

如@cnicutar和@ouah所述,atoi无法区分有效的0和无效的字符串,使strtol系列的选项更好。

为什么?如何?首先要了解atoistrtol只将字符串中的初始数字转换为数字值。任何尾随的非数字字符都会被忽略。 strtol可用于检查无效字符串,因为除了数值之外,它还返回指向字符串数字部分末尾的指针。因此,如果此end指针仍指向原始字符串的开头,则可以判断出存在错误,并且未转换字符串中的字符。

还有一些其他细微之处,如代码示例所示:

long lnum;
int num;
char *end;

errno = 0;

lnum = strtol(in_str, &end, 10);        //10 specifies base-10
if (end == in_str)     //if no characters were converted these pointers are equal
    fprintf(stderr, "ERROR: can't convert string to number\n");

//If sizeof(int) == sizeof(long), we have to explicitly check for overflows
if ((lnum == LONG_MAX || lnum == LONG_MIN) && errno == ERANGE)  
    fprintf(stderr, "ERROR: number out of range for LONG\n");

//Because strtol produces a long, check for overflow
if ( (lnum > INT_MAX) || (lnum < INT_MIN) )
    fprintf(stderr, "ERROR: number out of range for INT\n");

//Finally convert the result to a plain int (if that's what you want)
num = (int) lnum;

注意:如果您确定输入字符串将在有效的int范围内,则可以消除lnum并直接转换strtol的返回值:num = (int) strtolen(in_str, &end, 10);

答案 2 :(得分:6)

你不能。

atoi无法检测错误。如果无法表示结果,atoi将调用未定义的行为。使用strtol代替atoi

安全CERT编码建议使用strtol代替atoi,请阅读:

INT06-C. Use strtol() or a related function to convert a string token to an integer

答案 3 :(得分:-4)

我已经

"autoload": {
        "psr-4": { "Nyranith\\": "src/"
        }
    },

在使用atoi之前没有问题,但要注意它不能检测溢出或错误的输入。使用strtol有点棘手也请检查this以获取更多信息