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。
但为什么? 如何? 首先明白atoi
和strtol
只能将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有点棘手也检查此更多信息