我已经习惯了 strtod和变种。 我想知道为什么没有 strtoi与 <stdlib.h>一起发货。 为什么整数类型被忽略了呢?
strtod
strtoi
<stdlib.h>
具体来说,我要问为什么没有一个版本的 atoi与 strtod的安全功能?
atoi
它叫做 atoi。详情请参阅 维基百科,包括它的继承者 strol。
strol
整数没有被忽略: 有一个 strtol,它将字符串转换为一个 long,这是一个整数类型。
strtol
long
不要忽略手册中的 SEE ALSO部分:)
SEE ALSO
SEE ALSO atof(3), atoi(3), atol(3), strtol(3), strtoul(3)
你要找的是 atoi(3)
atoi(3)
strtol()将一个字符串转换为一个整数,一个长整数,但仍然是一个整数。有 atoi(),但是在大多数情况下应该避免它,因为它缺乏一种机制来报告无效输入的错误。
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()中进行-如下所示。
int
这些和它们的 unsigned对应物现在缺少 C 函数,并且是当前标准 C 库(C17/18)中的一个设计缺陷。
unsigned
在许多系统中,long和 int有相同的范围,因此减少了对单独 strtoi()的需求。atoi()填补了快速和肮脏的代码转换为 int的需要,但可能缺乏错误检测。错误时,atoi()引发 未定义行为(UB)。也没有 strto_short()或 strto_signchar()等等。
strtoi()
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。
strto...()
str2...()
to
以 str、 mem或 wcs开头的函数名和小写字母可以添加到 <string.h>标题中的声明中。C17dr 7.31.131
str
mem
wcs
<string.h>