Почему в stdlib.h нет strtoi? - PullRequest
58 голосов
/ 31 мая 2011

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

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

Ответы [ 6 ]

46 голосов
/ 31 мая 2011

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

21 голосов
/ 31 марта 2015

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

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

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

IMO, у этих и их 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);
}
5 голосов
/ 31 мая 2011

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

2 голосов
/ 09 сентября 2013

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

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;
0 голосов
/ 31 мая 2011

Не пропустите раздел SEE ALSO на ваших страницах:)

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

Вы ищете atoi(3).:)

0 голосов
/ 31 мая 2011

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

...