ZetCode

C strtol 函数

最后修改:2025 年 4 月 8 日

字符串到数字的转换是 C 编程中的一项常见任务,而 strtol 是一个功能强大的函数。本教程将深入介绍 strtol,包括其语法、用法和错误处理。我们将探讨为什么 strtolatoi 等函数更安全,并提供实际示例。理解 strtol 有助于在处理字符串中的数字输入时编写更可靠的代码。

什么是 strtol?

strtol 函数将字符串转换为长整数。它在 stdlib.h 中声明,并提供强大的错误检查。与 atoi 不同,strtol 可以检测转换错误并支持不同的数字基数。它接受三个参数:要转换的字符串、一个用于存储结束位置的可选指针以及数字基数。为了可靠地进行字符串转换,请始终优先选择 strtol 而不是 atoi

strtol 的基本用法

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

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

int main() {
    char str[] = "12345";
    char *endptr;
    long num;

    num = strtol(str, &endptr, 10);

    if (*endptr != '\0') {
        printf("Conversion error: non-numeric characters\n");
        return 1;
    }

    printf("Converted number: %ld\n", num);
    return 0;
}

在此,strtol 使用基数 10 将字符串 "12345" 转换为长整数。endptr 通过指向第一个无效字符来帮助检测转换错误。我们检查 *endptr 是否为 null 终止符,以确保完全转换。这种方法比不提供错误检测的 atoi 安全得多。

处理不同的数字基数

strtol 可以转换各种基数的数字,如下例所示。

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

int main() {
    char hex_str[] = "1a3f";
    char bin_str[] = "101011";
    char *endptr;
    long hex_num, bin_num;

    hex_num = strtol(hex_str, &endptr, 16);
    if (*endptr != '\0') {
        printf("Hex conversion error\n");
        return 1;
    }

    bin_num = strtol(bin_str, &endptr, 2);
    if (*endptr != '\0') {
        printf("Binary conversion error\n");
        return 1;
    }

    printf("Hex %s = %ld\n", hex_str, hex_num);
    printf("Binary %s = %ld\n", bin_str, bin_num);
    return 0;
}

此示例转换了一个十六进制字符串(基数 16)和一个二进制字符串(基数 2)。第三个参数指定数字基数。基数 0 允许 strtol 从字符串前缀(十六进制的 0x,八进制的 0)自动检测基数。始终检查 endptr 以验证整个字符串是否成功转换。

使用 strtol 进行错误检测

此示例演示了对 strtol 进行全面的错误处理。

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

int main() {
    char str[] = "99999999999999999999";
    char *endptr;
    long num;

    errno = 0;
    num = strtol(str, &endptr, 10);

    if (errno == ERANGE) {
        printf("Number out of range\n");
        if (num == LONG_MAX) printf("Overflow occurred\n");
        if (num == LONG_MIN) printf("Underflow occurred\n");
        return 1;
    }

    if (*endptr != '\0') {
        printf("Conversion stopped at: %s\n", endptr);
        return 1;
    }

    printf("Converted number: %ld\n", num);
    return 0;
}

此代码显示了如何在转换非常大的数字时检测范围错误 (ERANGE)。我们会在转换后检查 errno 以识别溢出/下溢。该示例还演示了检查 endptr 以进行部分转换。适当的错误处理使 strtol 比简单的转换函数可靠得多。

从混合字符串解析数字

此示例展示了如何从包含非数字数据的字符串中提取数字。

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

int main() {
    char input[] = "values: 42, 17, 99, xyz";
    char *ptr = input;
    char *endptr;
    long num;

    // Skip non-numeric prefix
    while (*ptr && (*ptr < '0' || *ptr > '9')) ptr++;

    while (*ptr) {
        num = strtol(ptr, &endptr, 10);
        
        if (ptr == endptr) break; // No conversion
        
        printf("Found number: %ld\n", num);
        
        // Move to next potential number
        ptr = endptr;
        while (*ptr && (*ptr < '0' || *ptr > '9')) ptr++;
    }

    return 0;
}

此代码从包含混合内容的字符串中解析多个数字。它使用 endptr 在每次转换后推进字符串。循环会跳过数字之间的非数字字符。此技术对于处理配置文件或用户输入(其中数字出现在其他文本中)非常有用。该示例演示了 strtol 在实际解析场景中的灵活性。

安全替代方案:带输入验证的 strtol

此示例演示了一个用于更安全地使用 strtol 的包装器函数。

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

int safe_strtol(const char *str, long *result) {
    char *endptr;
    
    if (str == NULL || *str == '\0') {
        return 0; // Empty string
    }

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

    if (errno == ERANGE) {
        return 0; // Out of range
    }

    if (*endptr != '\0') {
        return 0; // Extra characters
    }

    return 1; // Success
}

int main() {
    char input[100];
    long num;

    printf("Enter a number: ");
    fgets(input, sizeof(input), stdin);

    if (safe_strtol(input, &num)) {
        printf("Valid number: %ld\n", num);
    } else {
        printf("Invalid input\n");
    }

    return 0;
}

safe_strtol 函数提供全面的输入验证。它会检查空字符串、范围错误和尾随字符。此包装器使 strtol 在生产代码中的使用更加方便和安全。该示例展示了如何将其与来自 fgets 的用户输入一起使用。在处理不受信任的输入时,此类验证至关重要。

使用 strtol 的最佳实践

来源

C strtol 文档

本教程探讨了 strtol 函数,从基本用法到高级错误处理。正确的字符串转换对于健壮的 C 程序至关重要,而 strtol 提供了可靠运行所需的工具。始终优先选择它,而不是像 atoi 这样更简单但不安全的替代方案。

作者

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

列表 C 标准库