文字列をstdint.h整数に変換する標準関数を探しています。
int i = atoi("123");
unsigned long ul = strtoul("123", NULL, 10);
uint32_t n = mysteryfunction("123"); // <-- ???
文字列をstdint.h整数に変換する標準関数を探しています。
int i = atoi("123");
unsigned long ul = strtoul("123", NULL, 10);
uint32_t n = mysteryfunction("123"); // <-- ???
2つの一般的なオプションがあります。strto[iu]max値が小さいタイプに適合するかどうかを確認するためのチェックが続くか、に切り替えsscanfます。<inttypes.h>C標準は、タイプの適切な変換指定子に拡張されるマクロのファミリー全体を定義し<stdint.h>ます。例uint32_t:
#include <inttypes.h>
#include <stdio.h>
int main()
{
uint32_t n;
sscanf("123", "%"SCNu32, &n);
printf("%"PRIu32"\n", n);
return 0;
}
(の場合uint32_t、strtoul+オーバーフローチェックは少なくとも32ビット幅でuint32_tあるため、に対しても機能します。、などに対しては確実に機能しません。)unsigned longuint_least32_tuint_fast32_tuint64_t
編集:Jens Gustedtが以下に記しているように、これはstrtoulベースを指定できないという点での完全な柔軟性を提供しません。ただし、基数8と基数16は、それぞれSCNo32とで取得できSCNx32ます。
あなたの質問はunsigned整数に関するので、オーバーフローチェックは簡単です。少しヘルパー機能付き
inline
unsigned long long
strtoullMax(const char *nptr,
char **endptr,
int base,
unsigned long long maxval) {
unsigned long long ret = strtoll(nptr, endptr, base);
if (ret > maxval) {
ret = maxval;
errrno = ERANGE;
} else {
if (ret == ULLONG_MAX && errno == ERANGE)
ret = maxval;
}
return ret;
}
興味のあるタイプのトリックを実行するマクロを簡単に定義できます
#define strtou32(NPTR, ENDPTR, BASE) \
strtoullMax(NPTR, ENDPTR, BASE, (uint32_t)-1)
#define strtou32f(NPTR, ENDPTR, BASE) \
strtoullMax(NPTR, ENDPTR, BASE, (uint_fast32_t)-1)
#define strtou32l(NPTR, ENDPTR, BASE) \
strtoullMax(NPTR, ENDPTR, BASE, (uint_least32_t)-1)