ZetCode

C atoi 函数

最后修改:2025 年 4 月 8 日

在 C 编程中,字符串到整数的转换是一项常见任务,而 `atoi` 是为此目的而设计的 But not safe function。本教程将深入介绍 `atoi`,包括其语法、用法和局限性。我们将探讨实际示例,并讨论 `strtol` 等更安全的替代方案,以实现健壮的应用程序。了解字符串转换函数有助于有效处理用户输入和文本数据。

什么是 atoi?

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

基本的 atoi 用法

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

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

int main() {
    char num_str[] = "12345";
    int num = atoi(num_str);

    printf("String: %s\n", num_str);
    printf("Integer: %d\n", num);

    return 0;
}

在这里,`atoi` 将字符串 "12345" 转换为整数 12345。该函数会自动处理前导空白字符。这对于格式良好的数字字符串效果很好。但是,它没有提供检测无效输入的方法。对于用户输入或不受信任的数据,请考虑更安全的替代方案。

处理无效输入

此示例显示了 `atoi` 对无效输入的行为。

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

int main() {
    char invalid1[] = "abc123";
    char invalid2[] = "123abc";
    
    printf("\"%s\" converts to %d\n", invalid1, atoi(invalid1));
    printf("\"%s\" converts to %d\n", invalid2, atoi(invalid2));

    return 0;
}

`atoi` 对不以数字开头的字符串("abc123")返回 0。它转换前导数字但会忽略尾随的非数字字符("123abc" 变为 123)。这种静默失败可能导致程序中的错误。该函数也不会检测溢出 - 大数字可能会返回意外的值。

安全替代方案:strtol

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

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

int main() {
    char input[] = "123456789012345";
    char *endptr;
    long num;
    
    errno = 0;
    num = strtol(input, &endptr, 10);
    
    if (errno == ERANGE) {
        printf("Number out of range\n");
    } else if (*endptr != '\0') {
        printf("Invalid characters in input\n");
    } else {
        printf("Converted number: %ld\n", num);
    }

    return 0;
}

`strtol` 提供健壮的错误检查。它会在溢出时设置 `errno`,并返回指向第一个无效字符的指针。第三个参数指定数字的基数(10 表示十进制)。这使得 `strtol` 适用于需要输入验证的生产代码。

转换多个数字

此示例展示了如何从字符串中转换多个数字。

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

int main() {
    char data[] = "42 99 17";
    int n1, n2, n3;
    
    n1 = atoi(data);
    n2 = atoi(data + 3);
    n3 = atoi(data + 6);
    
    printf("Numbers: %d, %d, %d\n", n1, n2, n3);

    return 0;
}

在这里,我们通过调整传递给 `atoi` 的指针来转换三个以空格分隔的数字。当输入格式已知且一致时,这种方法有效。对于更复杂的解析,最好使用 `strtok` 结合 `strtol`。以这种方式使用 `atoi` 时,请务必验证结果。

处理负数

此示例演示了 `atoi` 对负数的处理。

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

int main() {
    char neg_str[] = "-32768";
    char pos_str[] = "+2147483647";
    
    printf("\"%s\" converts to %d\n", neg_str, atoi(neg_str));
    printf("\"%s\" converts to %d\n", pos_str, atoi(pos_str));

    return 0;
}

`atoi` 可以正确处理负数和可选的正号。它遵循与正数相同的转换规则。但是,它仍然缺乏溢出检测 - 非常大的负数可能会发生环绕。为了进行完整的范围检查,`strtol` 仍然是更好的选择。

字符串转换的最佳实践

来源

C atoi 文档

本教程探讨了 `atoi` 函数,从基本用法到其局限性。虽然简单,但在输入验证和错误检测很重要的生产代码中,请务必考虑更安全的替代方案。

作者

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

列表 C 标准库