如何检查以确保在调用atoi()之前有一个整数?
我希望将整数作为命令行参数,但如果用户传递非整数字符串,则会导致堆栈溢出。 确保atoi()成功的标准方法是什么?
您可以使用:
long int strtol(const char *nptr, char **endptr, int base);
然后检查*endptr != nptr
。 这意味着字符串至少以整数开头。 您还可以检查* endptr指向终止为零,这意味着整个字符串已成功解析。
如果字符串包含除数字以外的字符, atoi()
将(应该)不会导致堆栈溢出。 它将简单地将从字符串开头找到的任何数字转换为int
,直到不再存在为止。
int x = atoi("12monkeys"); // x is 12 int y = atoi("monkeys12"); // y is 0
您可以检查在现代(当前)PC架构上没有整数溢出 (数字超出[-2 ^ 31,2 ^ 31-1]的范围)。
编辑 (评论)
虽然如果值无法表示,C标准会警告未定义的行为 ,但如果值不可接受,则最常见的C最近编译器(gcc,MS …)不会崩溃 (除非char *
指针为null或错误课程)。
无论如何,您可以轻松实现自己的atoi()
(与我的答案相同的限制)
#include int myatoi(char *s) { int res = 0, minus = *s == '-'; if (minus) s++; while (isdigit(*s)) { res = res*10 + (*s++ - '0'); } return minus ? -res : res; }
这不会导致堆栈溢出。 如果在字符串的开头找不到数字, atoi
返回0
。 您(非)处理0
是导致堆栈溢出的原因。
堆栈溢出? 好吧,我想如果字符串中的值溢出int
的范围,那么这是未定义行为的一种可能结果。 在实践中,它通常只是包装或返回虚假结果。
如果您想要更好的错误检查,请使用strtol
而不是atoi
。 它在溢出时具有明确定义的行为(它设置errno
,在调用strtol
之前需要将其清除为0,以便区分错误返回和返回的合法值),并且可以检查字符串中停止转换的点查看完整字符串是否为整数,或者是否有超出结尾的其他内容。
我不认为标准atoi会堆栈溢出,但是没有办法判断你是否没有整数。 使用strtol
– 可以处理非整数。
您可以执行此操作并输入Undefined Behavior land,您可以编写一个简单的validation函数,如下所示:
/* returns 0 on success, 1 on failure. */ int verify(char * string) { int x = 0; int len = strlen(string); while(x < len) { if(!isdigit(*(string+x))) return 1; ++x; } return 0; }
请注意, 在调用atoi() 之前必须调用此函数,并且需要string.h和stdio.h。
atoi()
如果只包含数字字符,则将字符串转换为整数,否则返回0。
这可能对你有帮助。 检查stdlib.h中的strtol