无符号整数的atoi等价函数

29

我正在进行两个关于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函数。 - mukunda
1
如果代码需要至少16位无符号,请使用“unsigned”。如果代码需要至少32位无符号,请使用“unsigned long”。如果代码需要恰好32位无符号,请使用“uint32_t”。 - chux - Reinstate Monica
2个回答

35
简单的答案是要使用 strtoul()
更长的答案是,即使您只需要有符号 32 位整数或者对于无符号整数只需要 31 位,atoi() 函数也不适合您所做的事情。
正如您已经注意到的,atoi() 函数将字符串转换为一个整数。一个普通的有符号整数。但是,atoi() 没有错误处理。atoi() 的规范所述是 "如果值不能表示,则行为是未定义的。"
strto*() 函数系列都清楚地说明了如何处理错误,因此在所有情况下,您应该用调用 strtol()(将字符串转换为 long)来替换 atoi(),在这种情况下,由于您想处理无符号整数,因此应该使用 strtoul() (将字符串转换为无符号 long)。
请注意,如果您想处理更大的数字,则可以使用 strtoll()strtoull() 函数,将字符串转换为 long long 或 unsigned long long。 (如果您只想处理最大可能的整数值而不必担心中间的所有内容,则有 strtoimax()strtoumax(),它们返回类型分别为 intmax_tuintmax_t 的值。)
POSIX 文档:
  • atoi():将字符串转换为整数。
  • strtol():将字符串转换为长整型。
  • strtoll():将字符串转换为长长整型。
  • strtoul():将字符串转换为无符号长整型。
  • strtoull():将字符串转换为无符号长长整型。
  • strtoimax():将字符串转换为最大整数值。
  • strtoumax():将字符串转换为最大无符号整数值。

很棒的答案。喜欢“未定义”的引用。我遇到了这个问题。我将一个约为70亿的小数值(适合于“unsigned long long”)放入“atoi()”中。我希望得到一个错误代码。但是我得到了“unsigned long long”的最大值。这个值是18亿亿。 - rustyMagnet
我非常喜欢微软关于 C 数据类型极限的文章 https://learn.microsoft.com/en-us/cpp/cpp/data-type-ranges?view=vs-2017。在处理 atoiint 返回类型时非常相关。 - rustyMagnet

2

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接