ZetCode

C atol 函数

最后修改:2025 年 4 月 8 日

字符串转换是 C 编程中的基础,而 `atol` 函数是用于将字符串转换为长整型(long integer)的函数。本教程将深入讲解 `atol`,包括其语法、用法和局限性。我们将探讨实际示例,并讨论更安全的替代方案,如 `strtol`。理解字符串转换有助于处理用户输入和配置文件数据,同时保持程序的安全性。

什么是 atol?

`atol` 函数将字符串转换为长整型。它声明在 `stdlib.h` 头文件中,并接受一个参数:要转换的字符串。`atol` 会跳过空白字符,然后转换后续字符,直到遇到非数字数据。它没有错误检测机制,对于无效输入返回 0。为了编写健壮的代码,建议使用 `strtol`,它提供错误检查并支持不同的进制。

atol 的基本用法

此示例演示了如何使用 `atol` 转换简单的数字字符串。

basic_conversion.c
#include <stdio.h>
#include <stdlib.h>

int main() {
    char num_str[] = "12345";
    long result = atol(num_str);

    printf("String: %s\n", num_str);
    printf("Converted long: %ld\n", result);

    return 0;
}

在此,`atol` 将字符串 "12345" 转换为长整型 12345。该函数会自动处理前导空白字符。虽然这很简单,但缺乏错误检查。如果 `num_str` 包含非数字字符,`atol` 会在第一个无效字符处停止转换。

处理无效输入

此示例展示了 `atol` 在处理无效输入时的行为。

invalid_input.c
#include <stdio.h>
#include <stdlib.h>

int main() {
    char input1[] = "42abc";
    char input2[] = "abc42";
    char input3[] = "   -123";

    printf("\"%s\" → %ld\n", input1, atol(input1));
    printf("\"%s\" → %ld\n", input2, atol(input2));
    printf("\"%s\" → %ld\n", input3, atol(input3));

    return 0;
}

这演示了 `atol` 的局限性。它将 "42abc" 转换为 42,忽略数字后面的字母。"abc42" 返回 0,因为转换在第一个字符处就失败了。该函数能正确处理带前导空白的 "-123"。这些行为表明了为什么 `atol` 在验证用户输入时是不安全的。

安全替代方案:strtol

此示例演示了更安全的 `strtol` 函数。

safe_conversion.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main() {
    char input[] = "123xyz";
    char *endptr;
    long result;

    errno = 0;
    result = strtol(input, &endptr, 10);

    if (errno != 0) {
        perror("Conversion error");
        return 1;
    }

    if (endptr == input) {
        printf("No digits found\n");
        return 1;
    }

    printf("Converted: %ld\n", result);
    printf("Remaining: %s\n", endptr);

    return 0;
}

`strtol` 通过 `errno` 和 `endptr` 参数提供强大的错误检查。它可以检测转换错误和部分转换。进制参数(此处为 10)支持不同的数字系统。这使得 `strtol` 适用于验证用户输入和配置文件,而在这些场景下使用 `atol` 会不安全。

转换大数字

此示例展示了 `atol` 如何处理大数字和溢出。

large_numbers.c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main() {
    char max_long[] = "2147483647";   // LONG_MAX typically
    char overflow[] = "99999999999999999999";

    printf("Max long: %ld\n", atol(max_long));
    printf("Overflow: %ld\n", atol(overflow));

    return 0;
}

`atol` 无法检测溢出——当数字超过 `LONG_MAX` 时,它会返回未定义的值。第一次转换可以正确进行,但第二次转换的结果是依赖于实现的,通常是 `LONG_MAX`。`strtol` 会将 `errno` 设置为 `ERANGE` 来指示溢出,这使其成为处理大数字的更好选择。

实际文件解析示例

此示例展示了 `atol` 在文件解析场景中的应用。

file_parsing.c
#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *file = fopen("data.txt", "r");
    if (!file) {
        perror("Failed to open file");
        return 1;
    }

    char buffer[100];
    long total = 0;

    while (fgets(buffer, sizeof(buffer), file)) {
        total += atol(buffer);
    }

    fclose(file);
    printf("Total: %ld\n", total);

    return 0;
}

这个简单的文件解析器使用 `atol` 来对文件中的数字求和。它假设每一行都包含一个有效的数字。在生产代码中,使用 `strtol` 进行错误处理会更好。该示例展示了 `atol` 在输入格式有保证的受控环境中的便利性。

字符串转换的最佳实践

来源

C atol 文档

本教程探讨了 `atol` 函数,从基本用法到其局限性。虽然它很方便,但在输入验证很重要的生产代码中,始终应考虑更安全的替代方案,如 `strtol`。

作者

我的名字是 Jan Bodnar,我是一名敬业的程序员,对编码充满热情。自 2007 年以来,我通过超过 1400 篇文章和 8 本电子书分享我的专业知识。凭借超过十年的教学经验,我致力于让编程变得易于理解和引人入胜。

列表 C 标准库