文字列を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 long
uint_least32_t
uint_fast32_t
uint64_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)