atoi 函数族和 strtol 函数族的区别与联系

atoi 函数族和 strtol 函数族都用来将字符串转换成数字。但是具体的区别和联系是什么呢?
通过查看 glibc 的函数源码,可以清楚的看到两者的关系。

两个函数族函数返回类型的对应关系。

返回类型atoi函数族strol函数族
intatoi
longatolstrtol
long longatollstrtoll
floatstrtof
doubleatofstrtod

函数原型

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

atoi 函数族的 glibc 实现:

atoi 的 glibc 实现:有一个强制类型转换

/* Convert a string to an int.  */
int
atoi (const char *nptr)
{
  return (int) strtol (nptr, (char **) NULL, 10);
}

atol 的 glibc 实现

/* Convert a string to a long int.  */
long int
atol (const char *nptr)
{
  return strtol (nptr, (char **) NULL, 10);
}

atoll 的 glibc 实现

/* Convert a string to a long long int.  */
long long int
atoll (const char *nptr)
{
  return strtoll (nptr, (char **) NULL, 10);
}

atof 的 glibc 实现

/* Convert a string to a double.  */
double
atof (const char *nptr)
{
  return strtod (nptr, (char **) NULL);
}

两者的关系说明。

从以上代码可以看出,atoi 函数族是 strtol 函数族的一种特例

以 atol 为例

/* Convert a string to a long int.  */
long int
atol (const char *nptr)
{
  return strtol (nptr, (char **) NULL, 10);
}

通过代码可以看出,atol 只是 strtol 在 10 进制下,且不考虑错误处理的情况下特殊情况。
atol 胜在易用性,但是不能进行其他进制的解析和错误处理。

注意:
虽然,atol 由 strtol实现,因此也会设置 errno,但是 errno 只有以下两种返回值:

  • EINVAL (not in C99): 进制值输入错误(支持的进制 [2, 36],即算上字母所能表达的数字范围)
  • ERANGE: 结果超出范围

因此不能通过 errno 判断以下情况解析是否正确:

  • “abc”
    atol 会返回 0,无法判断字符串是 “0” 还是未解析正确。
  • “123abc”
    atol 会返回 123, 但是后续的 “abc” 将无法继续解析。

strtol 的使用示例

以下示例取自 man strtol 中的示例代码:

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

int
main(int argc, char *argv[])
{
    int base;
    char *endptr, *str;
    long val;

    if (argc < 2) {
        fprintf(stderr, "Usage: %s str [base]\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    str = argv[1];
    base = (argc > 2) ? atoi(argv[2]) : 10;

    errno = 0;    /* To distinguish success/failure after call */
    val = strtol(str, &endptr, base);

    /* Check for various possible errors */

    if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
            || (errno != 0 && val == 0)) {
        perror("strtol");
        exit(EXIT_FAILURE);
    }

    if (endptr == str) {
        fprintf(stderr, "No digits were found\n");
        exit(EXIT_FAILURE);
    }

    /* If we got here, strtol() successfully parsed a number */

    printf("strtol() returned %ld\n", val);

    if (*endptr != '\0')        /* Not necessarily an error... */
        printf("Further characters after number: %s\n", endptr);

    exit(EXIT_SUCCESS);
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lylhw13_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值