Подтвердить что ты не робот

Atoi - как определить разницу между нулем и ошибкой?

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

Возвращаемое значение

При успешном выполнении функция возвращает преобразованное целое число как значение int. Если действительное преобразование не было выполнено, возвращается нулевое значение. Если правильное значение выходит за пределы диапазона отображаемых значений, возвращается INT_MAX или INT_MIN.

Итак, как я отличаюсь между atoi("poop") и atoi("0") и atoi("0000000")

Да, я могу выполнить цикл и проверить все нули в случае, если я получаю 0 результат, но не лучший способ?

Примечание. Я использую ANSI C89

4b9b3361

Ответ 1

Одна из причин atoi иногда считается небезопасной. Вместо этого используйте strtol/strtoul. И если вы используете его strtonum.

Функция atoi более опасна, чем вы думаете. В стандарте POSIX говорится:

Если значение не может быть представлено, поведение undefined.

В стандарте C99 также говорится:

7.20.1

Функции atof, atoi, atol и atoll не должны влиять на значение целочисленное выражение errno при ошибке. Если значение результата не может быть представлено, поведение не определено.

Ответ 2

Как описано @cnicutar и @ouah, atoi не может отличить допустимое значение 0 от недопустимой строки, что делает лучшие параметры семейства strtol.

Но Почему? и Как?. Сначала убедитесь, что оба atoi и strtol преобразуют только начальный набор чисел в строку в числовые значения. Любые конечные нечисловые символы просто игнорируются. strtol может использоваться для проверки недопустимых строк, поскольку в дополнение к числовому значению он также возвращает указатель на конец числовой части строки. Таким образом, если этот указатель end по-прежнему относится к началу исходной строки, вы можете сказать, что произошла ошибка, и никакие символы из строки не были преобразованы.

Есть несколько других тонкостей, как показано в примере кода:

long lnum;
int num;
char *end;

errno = 0;

lnum = strtol(in_str, &end, 10);        //10 specifies base-10
if (end == in_str)     //if no characters were converted these pointers are equal
    fprintf(stderr, "ERROR: can't convert string to number\n");

//If sizeof(int) == sizeof(long), we have to explicitly check for overflows
if ((lnum == LONG_MAX || lnum == LONG_MIN) && errno == ERANGE)  
    fprintf(stderr, "ERROR: number out of range for LONG\n");

//Because strtol produces a long, check for overflow
if ( (lnum > INT_MAX) || (lnum < INT_MIN) )
    fprintf(stderr, "ERROR: number out of range for INT\n");

//Finally convert the result to a plain int (if that what you want)
num = (int) lnum;

Примечание. Если вы уверены, что входная строка будет в пределах допустимого интервала int, вы можете исключить lnum и просто направить strtol return напрямую: num = (int) strtolen(in_str, &end, 10);

Ответ 3

Вы не можете.

atoi не может обнаружить ошибки. Если результат не может быть представлен, atoi вызывает поведение undefined. Используйте strtol вместо atoi.

Защищенная CERT-кодировка рекомендует использовать strtol вместо atoi, читать:

INT06-C. Используйте strtol() или связанную функцию для преобразования токена строки в целое число

Ответ 4

Я использовал

#include <stdlib.h>
using namespace std;

до main и без проблем при использовании atoi, но будьте осторожны, он не может обнаружить переполнение или неправильные входы. используя strtol немного сложно и проверьте этот для получения дополнительной информации