我正在寻找将字符串转换为stdint.h整数的标准函数,例如
int i = atoi("123");
unsigned long ul = strtoul("123", NULL, 10);
uint32_t n = mysteryfunction("123"); // <-- ???
答案 0 :(得分:8)
有两个常规选项: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
的完全灵活性,因为您无法指定基础。但是,仍然可以使用SCNo32
和SCNx32
获得基数8和基数16。
答案 1 :(得分:1)
由于您的问题涉及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)