atol()和strtol()有什么区别?
根据他们的手册页,它们似乎具有相同的效果以及匹配的参数:
long atol(const char *nptr);
long int strtol(const char *nptr, char **endptr, int base);
在一般情况下,当我不想使用base
参数(我只有十进制数字)时,应该使用哪个函数?
atol()和strtol()有什么区别?
根据他们的手册页,它们似乎具有相同的效果以及匹配的参数:
long atol(const char *nptr);
long int strtol(const char *nptr, char **endptr, int base);
在一般情况下,当我不想使用base
参数(我只有十进制数字)时,应该使用哪个函数?
Answers:
strtol
为您提供更大的灵活性,因为它实际上可以告诉您整个字符串是否已转换为整数。atol
,如果无法将字符串转换为数字(如中的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
可能仅适用于非常简单且受控制的情况。
simple_strtol
吗?if (!*end)
使用您的确切模型,我无法获得评估为真的条件。
如果有内存,则strtol()
具有将(可选)设置endptr
为指向无法转换的第一个字符的额外好处。如果为NULL
,则将其忽略。这样,如果您要处理包含数字和字符混合的字符串,则可以继续。
例如,
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;
}
if (!*end)
。它将指向字符串的null终止符(如果已将其全部转换),但本身不会设置为NULL。