为什么学校里没有学生?

我已经习惯了 strtod和变种。 我想知道为什么没有 strtoi<stdlib.h>一起发货。 为什么整数类型被忽略了呢?

具体来说,我要问为什么没有一个版本的 atoistrtod的安全功能?

67712 次浏览

它叫做 atoi。详情请参阅 维基百科,包括它的继承者 strol

整数没有被忽略: 有一个 strtol,它将字符串转换为一个 long,这是一个整数类型。

不要忽略手册中的 SEE ALSO部分:)

SEE ALSO
atof(3), atoi(3), atol(3), strtol(3), strtoul(3)

你要找的是 atoi(3)

strtol()将一个字符串转换为一个整数,一个长整数,但仍然是一个整数。有 atoi(),但是在大多数情况下应该避免它,因为它缺乏一种机制来报告无效输入的错误。

这是我一直在用的。

long long_val;
int  int_value;


errno = 0;
long_val = strtol (theString, NULL, 10);
if (errno)
handle_error;
if ((long) someIntMin > long_val || long_val > (long) someIntMax)
handle_invalid;
int_value = (int) long_val;

为什么学校里没有学生?

没有紧急需要。

在早期的 C 语言中,没有比 long更宽的标准有符号整数类型,所有更窄的转换,比如 int,都可以从 strtol()中进行-如下所示。

这些和它们的 unsigned对应物现在缺少 C 函数,并且是当前标准 C 库(C17/18)中的一个设计缺陷。


在许多系统中,longint有相同的范围,因此减少了对单独 strtoi()的需求。atoi()填补了快速和肮脏的代码转换为 int的需要,但可能缺乏错误检测。错误时,atoi()引发 未定义行为(UB)。也没有 strto_short()strto_signchar()等等。

创建一个替代 strtoi()相当容易。

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


static long str2subrange(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 str2i(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) str2subrange(s, endptr, base, INT_MIN, INT_MAX);
#endif
}


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


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


#include <stdint.h>
int16_t str2int16(const char *s, char **endptr, int base) {
return (int16_t) str2subrange(s, endptr, base, INT16_MIN, INT16_MAX);
}

[编辑2021]

为了避免与 未来图书馆的方向发生冲突,名称从 strto...()更改为 str2...()
意味着 to

strmemwcs开头的函数名和小写字母可以添加到 <string.h>标题中的声明中。C17dr 7.31.131