atol()v / s。 与strtol()
atol()&strtol()有什么区别?
根据他们的手册,他们似乎具有相同的效果以及相应的参数:
long atol(const char *nptr); long int strtol(const char *nptr, char **endptr, int base);
在一般情况下,当我不想使用base
参数(我只有十进制数)时,我应该使用哪个函数?
strtol
为您提供了更多的灵活性,因为它实际上可以告诉您整个string是否转换为整数。 atol
,当无法将string转换为数字(如在atol("help")
),返回0,这是无法区别atol("0")
:
int main() { int res_help = atol("help"); int res_zero = atol("0"); printf("Got from help: %d, from zero: %d\n", res_help, res_zero); return 0; }
输出:
Got from help: 0, from zero: 0
strtol
将使用其endptr
参数指定转换失败的位置。
int main() { char* end; int res_help = strtol("help", &end, 10); if (!*end) printf("Converted successfully\n"); else printf("Conversion error, non-convertible part: %s", end); return 0; }
输出:
Conversion error, non-convertible part: help
因此,对于任何严重的编程,我绝对推荐使用strtol
。 使用起来有点棘手,但是这有一个很好的理由,正如我上面所解释的那样。
atol
可能只适用于非常简单和受控的病例。
atol
function是strtol
function的一个子集,除了atol
没有提供可用的error handlingfunction。 ato...
函数最突出的问题是在溢出的情况下会导致未定义的行为。 注意:这不仅仅是在错误情况下缺乏信息反馈,这是未定义的行为 ,即通常是不可恢复的失败。
这意味着atol
函数(以及所有其他ato..
函数)对于任何严重的实际用途都是无用的。 这是一个devise错误,它的位置在C历史的垃圾场。 您应该使用strto...
group中的函数来执行转换。 除其他外,介绍了纠正ato...
集团职能固有的问题。
根据atoi
手册页,它已被strtol
弃用。
IMPLEMENTATION NOTES The atoi() and atoi_l() functions have been deprecated by strtol() and strtol_l() and should not be used in new code.
在新的代码中,我总是使用strtol
。 它有error handling, endptr
参数允许你看到哪个部分的string被使用。
C99标准规定了ato*
函数:
除了错误的行为,他们相当于
atoi: (int)strtol(nptr,(char **)NULL, 10)
atol: strtol(nptr,(char **)NULL, 10)
atoll: strtoll(nptr, (char **)NULL, 10)
atol(str)
相当于
strtol(str, (char **)NULL, 10);
如果你想要结束指针(检查是否有更多的字符要读取,或者实际上你已经读了什么)或者是一个非10的基数,那么使用strtol。否则,atol就可以。
如果内存服务, strtol()
将设置(可选) endptr
指向无法转换的第一个字符的附加好处。 如果为NULL
,则被忽略。 这样,如果你正在处理一个包含数字和字符混合的string,你可以继续。
例如,
char buf[] = "213982 and the rest"; char *theRest; long int num = strtol(buf, &theRest, 10); printf("%ld\n", num); /* 213982 */ printf("%s\n", theRest); /* " and the rest" */
strtol的手册页给出了以下内容:
ERRORS EINVAL (not in C99) The given base contains an unsupported value. ERANGE The resulting value was out of range. The implementation may also set errno to EINVAL in case no conversion was performed (no digits seen, and 0 returned).
以下代码检查范围错误。 (修改了Eli的代码)
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> int main() { errno = 0; char* end = 0; long res = strtol("83459299999999999K997", &end, 10); if(errno != 0) { printf("Conversion error, %s\n", strerror(errno)); } else if (*end) { printf("Converted partially: %i, non-convertible part: %s\n", res, end); } else { printf("Converted successfully: %i\n", res); } return 0; }