6

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

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

2 回答 2

9

有两个通用选项: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_tuint64_t

编辑:正如 Jens Gustedt 在下面指出的那样,这并不能提供strtoul您无法指定基础的全部灵活性。然而,底数 8 和底数 16 仍然可以分别用SCNo32和获得。SCNx32

于 2011-04-21T14:26:26.023 回答
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)
于 2011-04-21T20:34:33.800 回答