【问题标题】:Strtol() and atol() do not convert strings larger than 9 digitsstrtol() 和 atol() 不转换大于 9 位的字符串
【发布时间】:2011-02-11 17:55:18
【问题描述】:

在处理需要将字符串转换为长数字的应用程序时,atol() 和 strtol() 无法正确转换任何大于 9 位的字符串。

strtol 会提示一个与字符串无关的数字,而 atol 会导致一个负数(溢出)。

知道为什么会发生这种情况,我该如何解决?

【问题讨论】:

    标签: c string long-integer


    【解决方案1】:

    听起来您系统上的long 是一个 32 位值。这意味着任何高于 4,294,967,295 的无符号数都不会正确转换,也不会正确转换高于 2,147,483,647 或低于 2,147,483,648 的有符号数。

    一般来说,一个n位表示可以表示[-2n-1,-2n-1) 或 [0,2n) 范围内的无符号数。

    维基百科文章Computer numbering formats 可能是了解有关此行为的更多信息的一个很好的起点。

    您从atol()strtol() 看到不同结果的原因是它们具有不同的错误处理特性。来自strtol() man page

    strtol() 函数返回转换结果,除非值会下溢或溢出。如果发生下溢,strtol() 返回 LONG_MIN。如果发生溢出,strtol() 返回 LONG_MAX。在这两种情况下,errno 都设置为 ERANGE

    来自atol() man page

    atoi() 函数将 nptr 指向的字符串的初始部分转换为 int。行为与

    相同
    strtol(nptr, (char **)NULL, 10);
    

    除了 atoi() 不检测错误。

    atol()atoll() 函数的行为与 atoi() 相同,只是它们将字符串到他们的返回类型 longlong long

    【讨论】:

      【解决方案2】:

      这可能与您平台上long 的大小有关。在 32 位平台上,适合 long 的最大值是 2147483647 (2^31-1),因此任何大于此的值都不会适合。请改用long longstrtoll

      【讨论】:

      • 那是strtol给我的数字,所以这一定是平台的限制,strtoll工作了,非常感谢!
      【解决方案3】:

      您可能正在转换为 32 位整数。有一些库可以解决这个问题。

      尝试使用libgmp,它不会对整数的大小施加任何限制。

      【讨论】:

      • 是的,如果整数太大,您的程序将在未经您同意的情况下获得abort'ed...
      猜你喜欢
      • 2011-04-17
      • 2013-01-10
      • 1970-01-01
      • 2020-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多