Почему в stdlib.h нет strtoi?

Я привык к strtod и варианты. Мне интересно, почему нет strtoi, поставляемого с stdlib.h. Почему целое число не входит в эту группу?

В частности, я спрашиваю, почему нет версии Atoi с функциями безопасности strtod.

6 ответов

Решение

strtol() преобразует строку в целое число, длинное целое, но, тем не менее, целое число. Есть atoi() но этого следует избегать в большинстве случаев из-за того, что в нем отсутствует механизм сообщения об ошибках с неверного ввода.

Почему в stdlib.h нет strtoi?

Нет критической необходимости.

В раннем C не было стандартного подписанного типа шире, чем long и все более узкие преобразования, как int, может быть сделано из strtol() - как сделано ниже.

ИМО, эти и их unsigned у коллег в настоящее время отсутствуют функции C и недостаток дизайна в текущей стандартной библиотеке C.


На многих системах long а также int имеют одинаковый диапазон и поэтому существует необходимость в отдельном strtoi(), Так же atoi() удовлетворяет потребность в быстром и грязном коде, но может не обнаруживать ошибки. Там тоже нет strto_short() ни strto_signchar(), так далее.

Довольно легко создать замену strtoi(), Упрощения существуют.

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

static long strto_subrange(const char *s, char **endptr, int base, 
    long min, long max) {
  long y = strtol(s, endptr, base);
  if (y > max) {
    errno = ERANGE;
    return max;
  }
  if (y < min) {
    errno = ERANGE;
    return min;
  }
  return y;
}

// OP's goal
int strtoi(const char *s, char **endptr, int base) {
  #if INT_MAX == LONG_MAX && INT_MIN == LONG_MIN
    return (int) strtol(s, endptr, base);
  #else
    return (int) strto_subrange(s, endptr, base, INT_MIN, INT_MAX);
  #endif
}

short strtoshort(const char *s, char **endptr, int base) {
  return (short) strto_subrange(s, endptr, base, SHRT_MIN, SHRT_MAX);
}

signed char strtoschar(const char *s, char **endptr, int base) {
  return (signed char) strto_subrange(s, endptr, base, SCHAR_MIN, SCHAR_MAX);
}

#include <stdint.h>
int16_t strtoint16(const char *s, char **endptr, int base) {
  return (int16_t) strto_subrange(s, endptr, base, INT16_MIN, INT16_MAX);
}

Целое число не осталось вне партии: есть strtol, который преобразует строку в long, который является целочисленным типом.

Это то, что я использовал.

long long_val;
int  int_value;

errno = 0;
long_val = strtol (theString, NULL, 10);
if (errno)
   handle_error;
if ((long) someIntMin > long_val || long_val > (long) someIntMax)
   handle_invalid;
int_value = (int) long_val;

Не забывайте SEE ALSO раздел ваших руководств:)

SEE ALSO
       atof(3), atoi(3), atol(3), strtol(3), strtoul(3)

Ты ищешь atoi(3),:)

Это звонок atoi, См. Также Википедию для деталей, включая ее преемника strol,

Другие вопросы по тегам