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

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

返回值

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

所以我如何区别atoi("poop")atoi("0")atoi("0000000")

是的,我可以循环和检查所有的零,以防万一我得到0的结果,但没有一个更好的办法?

注意:我使用ANSI C89

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

atoi的function比你想象的更危险。 POSIX标准说:

如果该值不能表示,行为是未定义的。

C99标准也这样说:

7.20.1

函数atof,atoi,atol和atoll不需要影响整数expression式errno对一个错误的值。 如果结果的值不能表示,行为是不确定的。

正如@cnicutar和@ouah所描述的那样, atoi无法区分有效的0和无效的string,使得strtol系列更好的select。

为什么? 如何? 首先明白atoistrtol只能将string中的初始数字转换为数值。 任何尾随的非数字字符都会被忽略。 strtol可以用来检查无效的string,因为除了一个数值之外,它还会返回一个指向string数字部分末尾的指针。 因此,如果这个end指针仍然指向原始string的开头,那么可以说出现错误,并且没有字符被转换。

还有一些其他的细节,如代码示例中所示:

 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; 

注意:如果你确定inputstring在有效的int范围内,你可以省去lnum ,直接直接inputstrtol的返回值: num = (int) strtolen(in_str, &end, 10);

你不能。

atoi无法检测到错误。 如果结果不能被表示, atoi调用未定义的行为。 使用strtol而不是atoi

安全的CERT编码build议使用strtol而不是atoi ,阅读:

INT06-C。 使用strtol()或相关函数将string标记转换为整数

我用过了

 #include <stdlib.h> using namespace std; 

在使用atoi之前主要没有问题,但要小心它不能检测溢出或错误的input。 使用strtol有点棘手也检查此更多信息