为什么stdlib.h中没有strtoi?

Eli*_*Eli 61 c std

我已经习惯了strtod和变种.我想知道为什么stdlib.h没有附带strtoi.为什么整数被排除在这个派对之外?

具体来说,我问为什么没有版本的atoi具有strtod的安全功能.

Wiz*_*Wiz 46

strtol()将字符串转换为整数,然后是一个长整数但是整数.有atoi(),但在大多数情况下可避免由于缺乏对错误的无效输入报告机制的事实.

  • 当`long`的范围超出`int`的范围时,`strtol()`不会设置`errno`,也不会在`int`上返回`INT_MIN/MAX`,只会溢出,否定该安全功能的值. (7认同)
  • 由于答案没有详细说明如何在尝试转换为`int`时使用`strtol()`,指出表示`int`范围之外的值的字符串(但不是`long`)不设置` errno`也没有得到有限的价值.这与表示`long`范围之外的值的字符串不同:它设置`errno`并获得有限的值. (6认同)
  • @chux不确定你想说什么.当然,如果传递的值超出int的范围,则不是错误. (3认同)

chu*_*ica 23

为什么stdlib.h中没有strtoi?

没有迫切需要.

在早期的C中,没有标准的签名类型比long所有更窄的转换,例如int,可以从strtol()- 如下所述.

IMO,这些和他们的unsigned同行现在缺少C函数和当前标准C库中的设计缺点.


在许多系统上,long并且int具有相同的范围,因此减少了对单独的需求strtoi().此外,atoi()还满足快速和脏代码的需要,但缺乏错误检测.还有一个strto_short()也没有strto_signchar()等等.

创建替代品相当容易strtoi().存在简化.

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

static long strto_subrange(const char *s, char **endptr, int base, 
    long min, long max) {
  long y = strtol(s, endptr, base);
  if (y > max) {
    errno = ERANGE;
    return max;
  }
  if (y < min) {
    errno = ERANGE;
    return min;
  }
  return y;
}

// OP's goal
int strtoi(const char *s, char **endptr, int base) {
  #if INT_MAX == LONG_MAX && INT_MIN == LONG_MIN
    return (int) strtol(s, endptr, base);
  #else
    return (int) strto_subrange(s, endptr, base, INT_MIN, INT_MAX);
  #endif
}

short strtoshort(const char *s, char **endptr, int base) {
  return (short) strto_subrange(s, endptr, base, SHRT_MIN, SHRT_MAX);
}

signed char strtoschar(const char *s, char **endptr, int base) {
  return (signed char) strto_subrange(s, endptr, base, SCHAR_MIN, SCHAR_MAX);
}

#include <stdint.h>
int16_t strtoint16(const char *s, char **endptr, int base) {
  return (int16_t) strto_subrange(s, endptr, base, INT16_MIN, INT16_MAX);
}
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么这不是公认的答案。不知何故,您对所接受答案的评论没有得到足够的重视。 (2认同)
  • “strtonum”具有适得其反的语义:它在所有错误上返回“0”,在溢出时返回最小值或最大值是“strtol()”的一个功能,这使得可以轻松确定问题的原因。手册页声称*现有的替代方案,例如“atoi(3)”和“strtol(3)”,要么不可能,要么难以安全使用。*“atoi()”也是如此,但没有困难安全地使用“strtol()”。 (2认同)