2017-01-26 3 views
1

В языке программирования C строка, такая как "2147483649", переполняется как int, так как наибольший unsigned int равен 2147483647. Когда я хочу преобразовать строки целых чисел в int, как я могу проверить эти случаи переполнения?переполнение при изменении из строки в int в C

Я не могу просто проверить, если это >=-(2^32-1) и <= (2^32-1), так как процесс преобразования этой строки в int (например atoi()) уже изменяет это значение. Есть ли простой способ вместо проверки числа цифр строки перед преобразованием, а также каждой цифры за раз, чтобы убедиться, что она находится в диапазоне int?

+0

Почему 'atoi()'? Используйте 'strtol()'/'strtoll()' для лучшего. –

+1

Использование 'strtol',' atoi() 'не имеет проверки ошибок. Проверьте лимиты с 'LONG_MAX' и' LONG_MIN' с 'limits.h' – RoadRunner

+0

Возможно, это поможет вам: http://stackoverflow.com/questions/7456902/long-vs-int-cc-whats-the-point –

ответ

3

Использование atoi() для значения, которое не может быть представлено как целое, вызывает неопределенное поведение. То есть вы не должны использовать atoi().

Вместо этого вы можете использовать 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… 
} 
0

Использование strtol(). Он дает вам long, поэтому, если на вашей платформе больше int, вы можете проверить это для переполнения. И если номер в строке не подходит даже в long, функция вернет специальное значение LONG_MIN или LONG_MAX и установит errno.

0

Если вы разрабатываете свою собственную atoi функцию, вы можете проверить на переполнение, как вы набираете результат:

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 
5

Вы можете преобразовать полученное число обратно в строку и сравнить ее с исходной строкой. Хотя это не выглядит элегантно для меня. :-)

+0

Я собирался сказать то же самое. – selbie

+0

Это все еще вызывает неопределенное поведение. – kamikaze

Смежные вопросы