【问题标题】:what's the equivalent of atoi or strtoul for uint32_t and other stdint types?uint32_t 和其他 stdint 类型的 atoi 或 strtoul 等价物是什么?
【发布时间】:2011-08-10 08:41:43
【问题描述】:

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

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

【问题讨论】:

    标签: c type-conversion c99 stdint


    【解决方案1】:

    有两个常规选项:strto[iu]max,然后检查值是否适合较小的类型,或切换到 sscanf。 C 标准在&lt;inttypes.h&gt; 中定义了一整套宏,这些宏扩展为&lt;stdint.h&gt; 类型的适当转换说明符。 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,因为unsigned long至少有32位宽。它不能可靠地用于uint_least32_tuint_fast32_tuint64_t 等)

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

    【讨论】:

    • +1 但您正在失去能够指定基数的优势。
    • @Jens:不完全是。 SCNo32 处理基数 8,SCNx32 基数 16;所以只有奇异的基础和二进制没有被覆盖,二进制实现起来很简单。
    • @larsmans:最大的缺失不是外来碱基,而是strtouxxx 允许您指定0 的底数,在这种情况下,它是从数字推断出来的(通过解释它作为一个整数常量),如果您想允许(比如说)某人同时使用十六进制和十进制,这将非常有用。当然,结束指针有时也非常非常有用。
    • @Stephen:scanf 也有你的力量。只需使用%i 代替%d%o%x 等。
    • @R..: %i 是用于signed 目标对象,但不能简单地用于替换strtoul
    【解决方案2】:

    由于您的问题涉及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)
    

    【讨论】:

    • 为什么不使用uintmax_tstrtoumax,因为strtoumaxmax 太尴尬了;)?那些更安全,因为 IIRC 不能保证 uint_{fast,least}32_t 会小于 unsigned long long,而根据定义它们小于或等于 uintmax_t
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 2014-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多