c-atol()v / s。 strtol()

atol()和strtol()有什么区别?

根据他们的手册页,它们似乎具有相同的效果以及匹配的参数:

long atol(const char *nptr);

long int strtol(const char *nptr, char **endptr, int base);

在一般情况下,当我不想使用base参数(我只有十进制数字)时,应该使用哪个函数?

asked 2019-10-09T15:42:19Z
7个解决方案
82 votes

atol为您提供了更大的灵活性,因为它实际上可以告诉您整个字符串是否已转换为整数。 endptr,当无法将字符串转换为数字时(例如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

atol将使用其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

因此,对于任何认真的编程,我绝对建议使用atol。使用起来有些棘手,但这是有充分的理由的,正如我上面解释的那样。

atol仅适用于非常简单且受控制的情况。

Eli Bendersky answered 2019-10-09T15:43:05Z
20 votes

atol功能是ato..功能的子集,但strto...无法为您提供可用的错误处理功能。 ato...函数最突出的问题是,如果发生溢出,它们会导致未定义的行为。 注意:这不仅是在发生错误时缺乏信息反馈,而且还是未定义的行为,即通常无法恢复的故障。

这意味着atol功能(以及所有其他ato..功能)对于任何严重的实际用途几乎是无用的。 这是一个设计错误,它在C历史的垃圾场中。 您应该使用strto...组中的函数来执行转换。 除其他外,它们被引入以纠正ato...组功能固有的问题。

AnT answered 2019-10-09T15:43:48Z
18 votes

根据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.
jfmercer answered 2019-10-09T15:44:18Z
4 votes

在新代码中,我将始终使用strtol。它具有错误处理功能,并且atoi: (int)strtol(nptr,(char **)NULL, 10)参数允许您查看使用了字符串的哪一部分。

C99标准规定了atoi: (int)strtol(nptr,(char **)NULL, 10)功能:

除了错误行为外,它们等同于

atoi: (int)strtol(nptr,(char **)NULL, 10)
atol: strtol(nptr,(char **)NULL, 10)
atoll: strtoll(nptr, (char **)NULL, 10)

schot answered 2019-10-09T15:45:29Z
4 votes

atol(str)等同于

strtol(str, (char **)NULL, 10);

如果您要使用结束指针(检查是否有更多字符要读取,或者实际上您是否已经读过任何字符)或除10以外的其他基数,请使用strtol。

Andrew Stein answered 2019-10-09T15:46:12Z
2 votes

如果有内存,则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" */
Jeff Mercado answered 2019-10-09T15:46:49Z
1 votes

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;
}
Shriram V answered 2019-10-09T15:47:34Z
translate from https://stackoverflow.com:/questions/3792663/atol-v-s-strtol