对于uint32_t和其他stdint类型,atoi或strtoul相当于什么?

时间:2011-04-21 14:19:04

标签: c type-conversion c99 stdint

我正在寻找将字符串转换为stdint.h整数的标准函数,例如

int i = atoi("123");
unsigned long ul = strtoul("123", NULL, 10);
uint32_t n = mysteryfunction("123"); // <-- ???

2 个答案:

答案 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_tuint_fast32_tuint64_t等。)

修改:正如Jens Gustedt在下面所说,这不能提供strtoul的完全灵活性,因为您无法指定基础。但是,仍然可以使用SCNo32SCNx32获得基数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)