私はstrtod
とその変種に慣れてきました。 stdlib.hにstrtoiが同梱されていないのはなぜですか。整数がこのパーティーから除外されているのはなぜですか?
具体的には、strtodの安全機能を備えたatoiのバージョンがない理由を尋ねています。
strtol()
は、文字列を整数、長整数ですが、それでも整数に変換します。 atoi()
がありますが、無効な入力からエラーを報告するメカニズムがないため、ほとんどの場合は回避する必要があります。
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);
}
整数はパーティーから除外されません。文字列を整数型である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;