我正在寻找将字符串转换为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"); // <-- ???
有两个通用选项:strto[iu]max
然后检查值是否适合较小的类型,或者切换到sscanf
. C 标准定义了整个宏系列,<inttypes.h>
其中扩展为<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
+ 溢出检查的情况下也适用,uint32_t
因为unsigned long
它至少有 32 位宽。它不能可靠地适用于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)