【问题标题】:How can we convert a string to int for very large integer values?对于非常大的整数值,我们如何将字符串转换为 int?
【发布时间】:2011-12-03 14:25:57
【问题描述】:

我已经使用函数atoi 将字符串转换为int 并且它工作正常但是当我给了

num = atoi (argv[1]) ;

// argv contain 4294967295 maximun value of 32 bit integer

它给了我 2147483647 的答案,基本上是 4294967295 的一半

我猜这是因为char 和int 中的字节不同。 任何人都可以解释位和字节发生了什么 以及如何修复它或将其转换为 int

【问题讨论】:

  • 2147483647 是有符号整数的最大值(从 -2147483648 到 2147483647)。在那里用作返回值。您的值是 unsigned int 的最大值(范围从 0 到 4294967295)。
  • 除了下面建议的 sscanf 之外,您还可以使用 long 代替 int 然后使用 strtol() 或 strtoul()。
  • 您想将 a char 转换为 int(即表示 int 中特定 char 的值)或所以您的意思是将 string 的一部分解释为表示十进制值?您的问题标题更接近前者,但您的示例代码正在执行后者。
  • @dmckee 先生,我想将字符串转换为 int 我的字符串基本上是作为命令行参数给出的

标签: c linux char int


【解决方案1】:

如果您想认真处理非常大数字then you need a library like GMP。

GMP 代表 GNU Multiple Precision,它是一个 BigNum 库,这意味着它具有处理大于 32 位或 64 位的整数的代码。它可以处理与 RAM 一样多的位。

要将字符串转换为整数,您可以使用 GMP 函数 mpz_set_str()

【讨论】:

    【解决方案2】:

    您可以将strtoull 用于很长的数字。

    unsigned long long int strtoull(const char *nptr, char **endptr,
                                           int base);
    

    使用 C99 支持编译 -std=c99 或在 man strtoull 中提供定义以获取定义。

    【讨论】:

      【解决方案3】:

      您遇到了整数的最大值。由于atoi 返回一个int,它被限制为您机器上的整数大小。看起来您的机器使用 32 位 ints。

      如果你错过了(很容易错过),2147483647 = (2 ^ 31) - 1。请记住,ints 可以为负数,在这种情况下,最左边的位是符号位。这就是为什么您看到这个数字被“限制”为 2147483647。

      尝试将num 定义为unsigned int 而不是int,并使用strtoul 而不是atoi。

      【讨论】:

      • 仅此一项并没有帮助,因为atoi 的 UB 值超出了int 的范围。你需要strtoul 或类似的。
      • 这是真的。我相应地更新了我的答案。谢谢提醒。
      • @ZachRattner: stroul 据我所知不是标准函数 :)
      • @Mat:是的。检查 C 标准(ISO 9899,您可以通过 Google 找到它),第 7.20.1.4 节。
      • 为读者澄清:stroul 是一个错字。 strtoul 是完全标准的。
      【解决方案4】:

      使用strtoul 代替atoi。如果值溢出int,后者会导致未定义的行为,这就是您的情况。

      【讨论】:

        猜你喜欢
        • 2013-07-20
        • 1970-01-01
        • 2012-10-09
        • 1970-01-01
        • 1970-01-01
        • 2013-11-12
        • 2017-04-04
        • 2012-04-06
        • 1970-01-01
        相关资源
        最近更新 更多