2

In the C programming language, a string such as "2147483649" overflows as an int since the largest unsigned int is 2147483647. When I want to convert strings of integers to ints, how do I go about checking for these overflow cases?

I can't just check if it is >=-(2^32-1) and <= (2^32-1) since the process of converting this string to an int (eg atoi()) already changes this value. Is there an easy way instead of checking the number of digits of the string before converting and also each digit at a time to make sure it's within the range of ints?

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
domoremath
  • 555
  • 2
  • 8
  • 17

4 Answers4

7

You can convert the resulting integer back to string and compare it to the source string. Although it doesn't look elegant to me. :-)

D. Mika
  • 2,577
  • 1
  • 13
  • 29
5

Using atoi() on a value that cannot be represented as an integer invokes undefined behaviour. I.e. you should not use atoi().

Instead you can use strtol():

#include <stdlib.h>
#include <errno.h>

long val = strtol("2147483649", 0, 10);
if (val == LONG_MIN && errno == ERANGE) {
    …underflow…
} else if (val == LONG_MAX && errno == ERANGE) {
    …overflow…
}
kamikaze
  • 1,529
  • 8
  • 18
0

Use strtol(). It gives you a long so if on your platform that's larger than an int you can check that for overflow. And if the number in the string doesn't even fit in a long, the function will return a special value LONG_MIN or LONG_MAX and set errno.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
-1

If you're implementing your own atoi function, you can check for overflow as you accumulate the result:

int value = 0;
for-each digit-character in string
    int newValue = value + ( 10 * place * digit-character )
    if newValue < value then die("overflow detected")
    value = newValue
next
Dai
  • 141,631
  • 28
  • 261
  • 374
  • 1
    One problem you've got there. I know because I wrote the same thing and found the bug, ahah. Try it with 6147483648 for example. On the second last iteration, when you multiply 614748364 by 10, it overflows twice and it still ends up at x mod 2^31 = 1852516352, larger than the previous iteration. – NathanTempelman Jan 03 '19 at 00:50