web-dev-qa-db-ja.com

stdlib.hにstrtoiがないのはなぜですか?

私はstrtodとその変種に慣れてきました。 stdlib.hにstrtoiが同梱されていないのはなぜですか。整数がこのパーティーから除外されているのはなぜですか?

具体的には、strtodの安全機能を備えたatoiのバージョンがない理由を尋ねています。

58
Eli

strtol()は、文字列を整数、長整数ですが、それでも整数に変換します。 atoi()がありますが、無効な入力からエラーを報告するメカニズムがないため、ほとんどの場合は回避する必要があります。

46
Wiz

Stdlib.hにstrtoiがないのはなぜですか?

重大な必要はありません。

初期のCでは、longよりも広い標準の符号付き型はなく、以下のように、intなどのより狭い変換はすべてstrtol()から実行できました。

IMO、これらおよびそれらのunsignedカウンターパートは現在、C関数と現在の標準Cライブラリの設計上の欠点を欠いています。


多くのシステムでは、longintの範囲は同じであるため、個別の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);
}
22
chux

整数はパーティーから除外されません。文字列を整数型であるstrtolに変換するlongがあります。

5
James McNellis

これは私が使用しているものです。

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;
2
Marc K.