ZetCode

C atoll 函数

最后修改:2025 年 4 月 8 日

在 C 编程中,字符串到数字的转换是一项常见任务,而 atoll 是一个用于将字符串转换为长长整型(long long)整数的函数。本教程将深入介绍 atoll,包括其语法、用法和局限性。我们将探讨实际示例,并讨论更安全的替代方法,如用于关键应用程序的 strtoll。了解字符串转换函数有助于安全可靠地处理用户输入和配置文件数据。

什么是 atoll?

atoll 函数将字符串转换为长长整型。它在 stdlib.h 中声明,并接受一个参数:要转换的字符串。atoll 会跳过空白字符,然后将后续字符转换为数字。它没有错误检测功能,对无效输入返回 0。为了代码的健壮性,请考虑使用 strtoll,它提供错误检查并支持不同的基数。

atoll 的基本用法

此示例演示了使用 atoll 进行基本字符串到长长整型转换。

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

int main() {
    char num_str[] = "123456789012345";
    long long num = atoll(num_str);

    printf("String: %s\n", num_str);
    printf("Converted number: %lld\n", num);

    return 0;
}

在此,atoll 将字符串 "123456789012345" 转换为其数值等价物。该函数可以处理适合长长整型的数字。请注意,atoll 不会检测溢出——过大的值会发生环绕。在生产代码中使用 atoll 时,务必在转换前验证输入字符串。

处理无效输入

此示例展示了 atoll 对无效输入字符串的行为。

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

int main() {
    char invalid1[] = "abc123";
    char invalid2[] = "";
    char partial[] = "123abc";

    printf("'%s' -> %lld\n", invalid1, atoll(invalid1));
    printf("'%s' -> %lld\n", invalid2, atoll(invalid2));
    printf("'%s' -> %lld\n", partial, atoll(partial));

    return 0;
}

对于完全非数字字符串和空字符串,atoll 返回 0。对于以数字开头的字符串,它会转换开头的数字部分。这种行为可能会掩盖错误,因此对于健壮的输入验证,strtoll 更受欢迎。在使用 atoll 时,始终检查输入字符串以确保它们包含有效的数字数据。

安全替代方案:strtoll

此示例演示了更安全的带错误检查的 strtoll 函数。

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

int main() {
    char num_str[] = "12345678901234567890";
    char *endptr;
    long long num;

    errno = 0;
    num = strtoll(num_str, &endptr, 10);

    if (errno == ERANGE) {
        printf("Number out of range\n");
    } else if (endptr == num_str) {
        printf("No digits found\n");
    } else if (*endptr != '\0') {
        printf("Extra characters after number\n");
    } else {
        printf("Converted number: %lld\n", num);
    }

    return 0;
}

strtoll 通过 errnoendptr 参数提供健壮的错误检查。它可以检测溢出(设置 ERANGE)、无效输入和尾随字符。第三个参数指定数字的基数(10 表示十进制)。对于生产代码,由于 strtoll 具有全面的错误处理功能,因此推荐使用它而不是 atoll

转换不同基数的数字

此示例展示了如何使用 strtoll 从不同基数转换数字。

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

int main() {
    char hex_str[] = "1a3f";
    char bin_str[] = "1011";
    char oct_str[] = "755";

    long long hex_num = strtoll(hex_str, NULL, 16);
    long long bin_num = strtoll(bin_str, NULL, 2);
    long long oct_num = strtoll(oct_str, NULL, 8);

    printf("Hex '%s' -> %lld\n", hex_str, hex_num);
    printf("Binary '%s' -> %lld\n", bin_str, bin_num);
    printf("Octal '%s' -> %lld\n", oct_str, oct_num);

    return 0;
}

通过更改第三个参数,strtoll 可以从各种基数转换数字。基数 16 处理十六进制,基数 2 处理二进制,基数 8 处理八进制。基数 0 会解释前缀(0x 表示十六进制,0 表示八进制)。这种灵活性使 strtoll 比仅处理十进制数的 atoll 更通用。务必指定正确的基数以获得准确的转换。

处理大数字

此示例演示了 atoll 在处理非常大的数字时的表现。

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

int main() {
    char max_ll[] = "9223372036854775807";
    char overflow[] = "9223372036854775808";

    long long num1 = atoll(max_ll);
    long long num2 = atoll(overflow);

    printf("Max long long: %lld\n", num1);
    printf("Overflow value: %lld\n", num2);
    printf("LLONG_MAX: %lld\n", LLONG_MAX);

    return 0;
}

atoll 可以正确转换最大的 64 位有符号整数,但对于更大的值会导致未定义行为。溢出情况可能返回 LLONG_MIN 或发生环绕。与 strtoll 不同,atoll 无法检测溢出。为了安全地处理大数字,请务必优先使用具有正确错误检查的 strtoll

字符串转换的最佳实践

来源

C atoll 文档

本教程介绍了 atoll 函数,从基本用法到其局限性。虽然它很简单,但在生产代码中,如果输入验证和错误处理很重要,请始终考虑更安全的替代方案,如 strtoll

作者

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

列表 C 标准库