I wish to take an integer as a command line argument, but if the user passes a non-integer string, this will cause a stack overflow. What is the standard way to ensure atoi() will be successful?
9 Answers
You can use:
long int strtol(const char *nptr, char **endptr, int base);
Then check if *endptr != nptr
. This means that the string at least begins with the integer.
You can also check that *endptr points to terminating zero, which means that the whole string was successfully parsed.

- 2,212
- 2
- 31
- 40
-
2Just to add that strtol() also modifies "errno". You will know if the integer is too big to fit a "long". Also, as Lou Franco said, atoi should not cause a stack overflow. In that case, your string must use unallocated memory. – user172818 Oct 04 '10 at 02:01
atoi()
will (should) not cause a stack overflow if the string contains characters other than digits. It will simply convert to an int
any digit it finds from the beginning of the string until there is no more.
int x = atoi("12monkeys"); // x is 12
int y = atoi("monkeys12"); // y is 0
You may check that there is no integer overflow (number outside the range of [-2^31, 2^31-1] on a modern (current) PC architecture).
edit (comments)
While the C standards warns about an undefined behavior if the value cannot be represented, the most common C recent compilers (gcc, MS...) do not crash if the value is not acceptable (unless the char *
pointer is null or wrong of course).
Anyway, you can implement your own atoi()
easily (with the same limitations as in my answer)
#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;
}

- 28,223
- 6
- 72
- 100
-
4C99 §7.20.1/1, "The functions `atof`, `atoi`, `atol`, and `atoll` need not affect the value of the integer expression `errno` on an error. If the value of the result cannot be represented, the behavior is undefined." – kennytm Oct 03 '10 at 16:28
-
3KennyTM is correct. In principle, `atoi("123456789101112131415");` could crash the program or do anything, since it's specified as UB. – R.. GitHub STOP HELPING ICE Oct 03 '10 at 16:30
This does not cause stack overflow. atoi
returns 0
if it can't find a number at the start of the string. Your (non-)handling of the 0
is what causes the stack overflow.

- 191,408
- 23
- 240
- 301
Cause a stack overflow? Well I suppose that's one possible result of the undefined behavior if the value in the string overflows the range of int
. In practice though it usually just wraps or returns a bogus result.
If you want better error checking, use strtol
instead of atoi
. It has well-defined behavior on overflow (it sets errno
, which you need to clear to 0 before calling strtol
so you can distinguish between error returns and legitimate values being returned) and you can examine the point in the string at which it stopped conversion to see if the full string was an integer or whether there's additional content past the end.

- 208,859
- 35
- 376
- 711
I don't think a standard atoi will stackoverflow, but there's no way to tell if you don't have an integer with it. Use strtol
instead -- it's possible to deal with non-integers.

- 87,846
- 14
- 132
- 192
This might help you. Check strtol available in stdlib.h

- 119
- 1
- 2
- 9

- 54,530
- 11
- 89
- 103
Either you can do this and enter Undefined Behavior land, you could write a simple validation function like so:
/* 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;
}
Please note you do have to call this function before you call atoi(), and you need string.h and stdio.h.

- 221
- 3
- 13
-
How does this prevent undefined behavior due to a potential integer overflow? The number could still be way too big to be represented in an int or any other standard integral data type. – Larry Sep 16 '21 at 07:10
To check for overflow, you can simply convert the number you got from atoi
back to string. Now compare this string with your input string. If they match, then it's not an overflow, otherwise it is.
See a psuedo code here:
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;
}
The function returns -1 if its an overflow else 0.

- 793
- 10
- 7