【问题标题】:Equivalent of atoi for unsigned integers等价于无符号整数的 atoi
【发布时间】:2015-01-31 08:12:38
【问题描述】:

我正在执行两个涉及 atoi 的操作,我想知道如何使用无符号整数执行此操作,因为 atoi 似乎将这些转换为有符号整数,从而导致环绕整数溢出。我想使用 32 位无符号整数,但 atoi 将我有效地限制为 31 位无符号整数。

 if (multiplication_is_safe(atoi(argv[1]),atoi(argv[3])))
    {
     printf("%s * %s = %u \n", argv[1], argv[3], atoi(argv[1]) * atoi(argv[3]));
      return 0;
    }  else

【问题讨论】:

  • atoll?我不确定它是否是标准的 C 函数。
  • 如果代码需要至少 16 位无符号,请使用 unsigned。如果代码至少需要 32 位无符号,请使用 unsigned long。如果代码需要正好 32 位无符号,请使用 uint32_t

标签: c integer-overflow atoi


【解决方案1】:

简单的答案是改用strtoul()

更长的答案是,即使您只需要有符号的 32 位整数或对无符号的 31 位感到满意,atoi() 函数也不适合您似乎正在做的事情。

正如您已经注意到的,atoi() 函数将字符串转换为整数。一个普通的有符号整数。然而,atoi() 没有 做的是错误处理。 atoi() 的规范说的是“如果无法表示值,则行为未定义。

strto*() 系列函数都清楚地指定了错误的处理方式,因此您应该在所有情况下将 atoi() 替换为对 strtol() 的调用(将字符串转换为长字符串),在这种情况下,因为您想要处理无符号整数,您应该使用strtoul()(将字符串转换为无符号长整数)。

另外请注意,如果您想处理更大的数字,可以使用 strtoll()strtoull() 函数将您的字符串转换为 long long 或 unsigned long long。 (如果您只想处理可能的最大整数值而不需要处理介于两者之间的所有内容,则有strtoimax()strtoumax(),它们分别返回intmax_tuintmax_t 类型的值。)

POSIX 文档:

【讨论】:

  • 很好的答案。喜欢undefined 的报价。我遇到了这个问题。我将大约 70 亿的十进制值(非常适合 unsigned long long)放入 atoi()。我希望有一个错误代码。相反,我得到了 unsigned long long 的 MAX 值?。这个价值是180亿。 ?
  • 我真的很喜欢微软关于 C 数据类型的限制https://docs.microsoft.com/en-us/cpp/cpp/data-type-ranges?view=vs-2017 的这篇文章在处理atoiint 返回类型时非常相关。
【解决方案2】:

根据您的平台,strtoul 可能是您想要的:

strtoul() 函数转换 nptr 中字符串的起始部分 根据给定的基数转换为无符号长整型值,它必须 介于 2 和 36 之间,或者是特殊值 0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-02
    • 2012-11-18
    相关资源
    最近更新 更多