对于 uint32_t 和其他 stdint 类型,atoi 或 strtoul 的等效项是什么?

发布于 2024-11-02 17:23:02 字数 251 浏览 1 评论 0原文

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

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

i'm looking for the standard functions to convert a string to an stdint.h integer, like

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

旧梦荧光笔 2024-11-09 17:23:02

有两个常规选项:strto[iu]max,然后检查该值是否适合较小的类型,或者切换到 sscanf。 C 标准在 中定义了整个宏系列,这些宏扩展为 类型的适当转换说明符。 uint32_t 示例:(

#include <inttypes.h>
#include <stdio.h>

int main()
{
    uint32_t n;

    sscanf("123", "%"SCNu32, &n);
    printf("%"PRIu32"\n", n);

    return 0;
}

对于 uint32_tstrtoul + 溢出检查也适用于 uint32_t,因为 < code>unsigned long 至少为 32 位宽,它不能可靠地用于 uint_least32_tuint_fast32_tuint64_t 等)

编辑:正如下面 Jens Gustedt 所指出的,这并不能提供 strtoul 的全部灵活性code> 因为您无法指定基础。然而,基数 8 和基数 16 仍然可以分别通过 SCNo32SCNx32 获得。

There are two general options: strto[iu]max followed by a check to see if the value fits in the smaller type, or switch to sscanf. The C standard defines an entire family of macros in <inttypes.h> that expand to the appropriate conversion specifier for the <stdint.h> types. Example for uint32_t:

#include <inttypes.h>
#include <stdio.h>

int main()
{
    uint32_t n;

    sscanf("123", "%"SCNu32, &n);
    printf("%"PRIu32"\n", n);

    return 0;
}

(In the case of uint32_t, strtoul + overflow check would also work for uint32_t because unsigned long is at least 32 bits wide. It wouldn't reliably work for uint_least32_t, uint_fast32_t, uint64_t etc.)

Edit: as Jens Gustedt notes below, this doesn't offer the full flexibility of strtoul in that you can't specify the base. However, base 8 and base 16 are still possible to obtain with SCNo32 and SCNx32, respectively.

空城之時有危險 2024-11-09 17:23:02

由于您的问题涉及无符号整数,因此溢出检查很简单。通过一些辅助函数,

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)

Since your question concerns unsigned integers the overflow check is simple. With a little helper function

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;
}

you easily can define macros that do the trick for any type you are interested in

#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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文