【问题标题】:overflow when change from string to int in C在C中从字符串更改为int时溢出
【发布时间】:2017-06-11 16:35:34
【问题描述】:

在 C 编程语言中,像 "2147483649" 这样的字符串会作为 int 溢出,因为最大的 unsigned int 是 2147483647。当我想将整数字符串转换为ints 时,我该如何检查这些溢出情况?

我不能只检查它是否是>=-(2^32-1)<= (2^32-1),因为将此字符串转换为int(例如atoi())的过程已经更改了此值。有没有一种简单的方法,而不是在转换之前检查字符串的位数以及一次检查每个数字以确保它在 ints 的范围内?

【问题讨论】:

  • 为什么使用atoi()?使用strtol() / strtoll() 效果更好。
  • 使用strtolatoi()没有错误检查。使用来自limits.hLONG_MAXLONG_MIN 检查限制
  • 这可能会对您有所帮助:stackoverflow.com/questions/7456902/…
  • 如果您需要转换更大的值如何使用atoll(如果您可以使用C99)?

标签: c string int


【解决方案1】:

您可以将结果整数转换回字符串并将其与源字符串进行比较。虽然它在我看来并不优雅。 :-)

【讨论】:

  • 我正要说同样的话。
  • 这仍然会调用未定义的行为。
【解决方案2】:

对不能表示为整数的值使用atoi() 会调用未定义的行为。 IE。你不应该使用atoi()

您可以改为使用strtol():

#include <stdlib.h>
#include <errno.h>

long val = strtol("2147483649", 0, 10);
if (val == LONG_MIN && errno == ERANGE) {
    …underflow…
} else if (val == LONG_MAX && errno == ERANGE) {
    …overflow…
}

【讨论】:

    【解决方案3】:

    使用strtol()。它给你一个long,所以如果在你的平台上大于int,你可以检查它是否溢出。如果字符串中的数字甚至不适合long,该函数将返回一个特殊值LONG_MINLONG_MAX 并设置errno

    【讨论】:

      【解决方案4】:

      如果您正在实现自己的atoi 函数,则可以在累积结果时检查溢出:

      int value = 0;
      for-each digit-character in string
          int newValue = value + ( 10 * place * digit-character )
          if newValue < value then die("overflow detected")
          value = newValue
      next
      

      【讨论】:

      • 你遇到了一个问题。我知道是因为我写了同样的东西并发现了错误,啊哈。例如,尝试使用 6147483648。在倒数第二次迭代中,当您将 614748364 乘以 10 时,它会溢出两次,但仍会在 x mod 2^31 = 1852516352 处结束,大于上一次迭代。
      猜你喜欢
      • 1970-01-01
      • 2014-05-26
      • 2020-10-02
      • 1970-01-01
      • 1970-01-01
      • 2013-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多