正如@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;
注意:如果您确定输入字符串将在有效的 int 范围内,您可以消除lnum
并直接转换 strtol 的 return:num = (int) strtolen(in_str, &end, 10);