Эквивалент atoi для целых чисел без знака

Я делаю две операции с участием atoi, и мне интересно, как я могу это сделать с целыми целыми знаками, потому что atoi, кажется, преобразует их в подписанный, вызывая переполнение целочисленного целого. Я хочу работать с 32-битными целыми без знака, но atoi ограничивает меня эффективно до 31-битного без знака.

 if (multiplication_is_safe(atoi(argv[1]),atoi(argv[3])))
    {
     printf("%s * %s = %u \n", argv[1], argv[3], atoi(argv[1]) * atoi(argv[3]));
      return 0;
    }  else

Ответ 1

Простым ответом является использование strtoul().

Более длинный ответ заключается в том, что даже если все, что вам нужно, было подписано 32-битными целыми числами или были довольны 31 битом для unsigned, функция atoi() плохо подходит для того, что вы, кажется, делаете.

Как вы уже отметили, функция atoi() преобразует строку в целое число. Нормальное целое число со знаком. Однако то, что atoi() не делает, это обработка ошибок. Спецификация atoi() говорит: " Если значение не может быть представлено, поведение не определено ".

Семейство функций strto *() четко определяет, как обрабатываются ошибки, поэтому во всех случаях вы должны заменить atoi() на вызовы strtol() (преобразовать строку в long), и в этом случае, поскольку вы хотите обрабатывать целые числа без знака, вы должны использовать strtoul() (преобразовать строку в unsigned long).

Также обратите внимание, что если вы хотите обрабатывать большие числа, существуют функции strtoll() и strtoull(), чтобы преобразовать вашу строку в длинный или беззнаковый длинный. (И если вы просто хотите обрабатывать максимально возможные интегральные значения, не беспокоясь обо всем этом, между ними есть strtoimax() и strtoumax(), которые возвращают значения типа intmax_t или uintmax_t соответственно.)

Документация POSIX:

Ответ 2

В зависимости от вашей платформы, strtoul, вероятно, вы хотите:

Функция strtoul() преобразует начальную часть строки в nptr в значение unsigned long int в соответствии с данной базой, которое должно быть между 2 и 36 включительно или быть специальным значением 0.