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

Nah*_*hum 40 c atoi

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

回报价值

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

那么我atoi("poop")atoi("0")和之间的区别如何atoi("0000000")

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

注意:我使用ANSI C89

cni*_*tar 36

这是其中一个原因atoi有时被认为是不安全的.使用strtol/ strtoul代替.如果你有它使用strtonum.

这个功能atoi比你想象的更危险.POSIX标准指出:

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

C99标准也说明了这一点:

7.20.1

函数atof,atoi,atol和atoll不需要影响错误的整数表达式errno的值.如果无法表示结果的值,则行为未定义.

  • 没有回答题主的问题。 (3认同)
  • @BeeOnRope 编辑队列已满。答案是:“它是未定义的,因此您无法可靠地确定差异” (3认同)

Bry*_*n P 14

正如@cnicutar和@ouah所描述的那样,atoi无法区分有效的0和无效的字符串,从而使strtol家庭成为更好的选择.

为什么呢?如何?首先要了解两者,atoi并且strtol只将字符串中的初始数字组转换为数值.任何尾随的非数字字符都会被忽略.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;
Run Code Online (Sandbox Code Playgroud)

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

  • 那里有很多很好,但是......如果`sizeof(int)== sizeof(long)`,你还没有检测到溢出.你应该在调用`strtol()`之前设置`errno = 0;`,然后你需要测试`((lnum == LONG_MAX || lnum == LONG_MIN)&& errno == ERANGE)`来发现溢出.虽然它可以完成这项任务,但是`strtol()`实际上很难正确使用 - 比你演示的更难. (3认同)

oua*_*uah 7

你不能.

atoi无法检测错误.如果无法表示结果,则atoi调用未定义的行为.用strtol而不是atoi.

安全CERT编码建议使用strtol而不是atoi,读取:

INT06-C.使用strtol()或相关函数将字符串标记转换为整数