C strtoll 函数
最后修改:2025 年 4 月 8 日
将字符串转换为数字是 C 编程中一项常见的任务,而 strtoll 是将字符串转换为长长整型的强大函数。本教程将深入介绍 strtoll,包括其语法、用法和错误处理。我们将探讨实际示例,并讨论为什么 strtoll 比 atoll 等替代方法更安全。理解 strtoll 有助于创建能够安全正确地处理数字输入的可靠程序。
什么是 strtoll?
strtoll 函数将字符串转换为长长整型。它声明在 stdlib.h 中,并提供强大的错误检查。与 atoll 不同,它可以检测转换错误并支持不同的基数。strtoll 接受三个参数:要转换的字符串、一个可选的指针用于存储结束位置,以及数字的基数。对于安全关键代码,请始终优先选择 strtoll 而非更简单但不安全的函数。
strtoll 的基本用法
此示例演示了将简单的十进制字符串转换为长长整型。
#include <stdio.h>
#include <stdlib.h>
int main() {
char *str = "123456789012345";
char *endptr;
long long num = strtoll(str, &endptr, 10);
if (*endptr != '\0') {
printf("Conversion stopped at: %s\n", endptr);
} else {
printf("Converted number: %lld\n", num);
}
return 0;
}
在这里,strtoll 将字符串以 10 为基数转换为长长整型。endptr 用于检测转换停止的位置。如果整个字符串都被转换,endptr 将指向空终止符。此示例显示了正确的错误检查,这与没有提供错误检测的 atoll 不同。请务必检查 endptr 来验证转换。
处理不同的基数
strtoll 可以将不同基数的数字转换为长长整型,如下所示。
#include <stdio.h>
#include <stdlib.h>
int main() {
char *hex_str = "0x1a3f";
char *bin_str = "101101";
char *oct_str = "0777";
char *endptr;
long long hex_num = strtoll(hex_str, &endptr, 0);
long long bin_num = strtoll(bin_str, &endptr, 2);
long long oct_num = strtoll(oct_str, &endptr, 8);
printf("Hex conversion: %lld\n", hex_num);
printf("Binary conversion: %lld\n", bin_num);
printf("Octal conversion: %lld\n", oct_num);
return 0;
}
此示例展示了不同基数的转换。基数 0 允许自动检测十六进制(0x 前缀)、八进制(0 前缀)或十进制。显式基数(2 用于二进制,8 用于八进制)会强制以该基数进行解释。该函数会跳过前导空格,并在遇到第一个无效字符时停止。这种灵活性使得 strtoll 对于各种输入格式都非常通用。
使用 strtoll 进行错误处理
此示例演示了使用 strtoll 进行全面的错误处理。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
int main() {
char *str = "999999999999999999999999";
char *endptr;
errno = 0;
long long num = strtoll(str, &endptr, 10);
if (errno == ERANGE) {
printf("Range error: ");
if (num == LLONG_MAX) printf("Overflow\n");
else if (num == LLONG_MIN) printf("Underflow\n");
} else if (*endptr != '\0') {
printf("Partial conversion: stopped at '%s'\n", endptr);
} else {
printf("Successful conversion: %lld\n", num);
}
return 0;
}
此代码展示了 strtoll 的正确错误处理。我们检查 errno 以处理范围错误(ERANGE),并检查返回值以处理溢出/下溢。endptr 用于检测部分转换。在调用 strtoll 之前,请务必将 errno 设置为 0,以区分当前错误和之前的错误。这种方法提供了比简单函数更全面的错误检测。
将 strtoll 用于用户输入
此示例展示了使用 strtoll 安全地处理用户输入。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main() {
char input[100];
printf("Enter a number: ");
fgets(input, sizeof(input), stdin);
char *endptr;
errno = 0;
long long num = strtoll(input, &endptr, 10);
if (endptr == input) {
printf("Error: No digits found\n");
} else if (*endptr != '\n' && *endptr != '\0') {
printf("Error: Invalid characters in input\n");
} else if (errno == ERANGE) {
printf("Error: Number out of range\n");
} else {
printf("You entered: %lld\n", num);
}
return 0;
}
在这里,fgets 安全地读取用户输入,而 strtoll 则进行完整的错误检查进行转换。我们验证是否转换了任何数字(endptr == input),检查是否有尾随字符,并处理范围错误。这种方法可以防止因无效输入而导致的程序崩溃,并提供清晰的错误消息。处理用户提供的数字时,请始终使用此模式。
strtoll 的高级功能
此示例演示了本地化感知转换和高级解析。
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main() {
setlocale(LC_NUMERIC, "de_DE.UTF-8"); // German locale uses ',' as decimal
char *str = "1.234.567"; // German thousand separators
char *endptr;
long long num = strtoll(str, &endptr, 10);
if (*endptr != '\0') {
printf("Stopped at: '%s'\n", endptr);
printf("Converted part: %lld\n", num);
} else {
printf("Full conversion: %lld\n", num);
}
return 0;
}
此示例展示了本地化设置如何影响 strtoll。在德语本地化中,句点是千位分隔符,而不是小数点。该函数在遇到第一个非数字字符时停止,但会返回已转换的部分。请注意,strtoll 仅处理整数部分 - 对于浮点数,请使用 strtod。这演示了 strtoll 在处理本地化数字格式时的行为。
使用 strtoll 的最佳实践
- 始终检查 errno: 在调用之前将其设置为 0,并在之后检查 ERANGE。
- 检查 endptr: 验证转换停止的位置,以检测无效输入。
- 优先选择 strtoll 而非 atoll:
strtoll提供了atoll所缺乏的错误检测。 - 谨慎处理本地化: 注意本地化特定的数字格式。
- 验证用户输入: 与
fgets等安全输入函数结合使用。
来源
本教程介绍了 strtoll 函数,从基本用法到高级功能。正确使用 strtoll 可以创建健壮的程序,通过全面的错误检测安全地处理数字输入转换。
作者
列表 C 标准库。