我希望将整数作为命令行参数,但如果用户传递非整数字符串,则会导致堆栈溢出。确保atoi()成功的标准方法是什么?
答案 0 :(得分:21)
您可以使用:
long int strtol(const char *nptr, char **endptr, int base);
然后检查是否*endptr != nptr
。这意味着字符串至少以整数开头。
您还可以检查* endptr指向终止为零,这意味着整个字符串已成功解析。
答案 1 :(得分:5)
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 *
指针当然为空或错误。)
无论如何,您可以轻松实现自己的atoi()
(与我的回答中的限制相同)
#include <ctype.h>
int myatoi(char *s) {
int res = 0, minus = *s == '-';
if (minus) s++;
while (isdigit(*s)) {
res = res*10 + (*s++ - '0');
}
return minus ? -res : res;
}
答案 2 :(得分:1)
这不会导致堆栈溢出。 atoi
如果在字符串的开头找不到数字,则返回0
。您(非)处理0
是导致堆栈溢出的原因。
答案 3 :(得分:1)
导致堆栈溢出?好吧,如果字符串中的值超出int
的范围,我认为这是未定义行为的一种可能结果。在实践中,它通常只是包装或返回虚假结果。
如果您想要更好的错误检查,请使用strtol
代替atoi
。它在溢出时具有明确定义的行为(它设置errno
,在调用strtol
之前需要将其清除为0,以便区分错误返回和返回的合法值)并且可以检查点在它停止转换的字符串中,查看完整字符串是否为整数,或者是否有超出结尾的其他内容。
答案 4 :(得分:0)
我认为标准atoi不会堆栈溢出,但是没有办法判断你是否没有整数。使用strtol
代替 - 可以处理非整数。
答案 5 :(得分:0)
这可能会对你有所帮助。检查stdlib.h中的strtol
答案 6 :(得分:0)
你可以这样做并输入Undefined Behavior land,你可以编写一个简单的验证函数,如下所示:
/* 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。
答案 7 :(得分:0)
atoi()
如果只包含数字字符,则将字符串转换为整数,否则返回0.
答案 8 :(得分:0)
要检查溢出,您可以简单地将您从 atoi
获得的数字转换回字符串。现在将此字符串与您的输入字符串进行比较。如果它们匹配,则不是溢出,否则是。
在此处查看伪代码:
int check_overflow(int num, char *arr, int len){
char buf[len + 1];
sprintf(buf, "%d", num);
if(strcmp(buf, arr) == 0){
return 0;
}
return -1;
}
如果溢出则函数返回-1,否则返回0。