1.引言
strtol() 是 C 语言标准库中的一个字符串转长整数(long int) 的函数,定义在 <stdlib.h> 头文件中。
#include <stdlib.h>
long int strtol(const char *str, char **endptr, int base);
二、参数说明
参数名 | 含义与作用 |
---|---|
str | 待转换的字符串(如 "123"、"0x1A"、"-456")。 |
endptr | 输出参数(指针的指针)。转换结束后,*endptr 指向字符串中第一个未被转换的字符(若为 NULL,则不返回此信息)。 |
base | 转换的基数(进制),取值范围:0:自动根据字符串前缀判断进制(推荐);2~36:指定进制(2 = 二进制,10 = 十进制,16 = 十六进制等)。 |
三、返回值
- 成功转换:返回转换后的长整数(long int 类型)。
- 转换失败(如字符串无有效数字):返回 0。
- 数值溢出(超出 long int 范围):返回 LONG_MAX(正溢出)或 LONG_MIN(负溢出),并设置全局变量 errno 为 ERANGE。
四、核心功能解析
1.自动跳过前导空白字符
转换前会自动忽略字符串开头的空白字符(空格 ' '、制表符 '\t'、换行符 '\n' 等)。
例如:strtol(" \t123", NULL, 10) 会跳过空格和制表符,转换 "123"。
2.基数(base)的作用
base = 0(自动判断):
- 字符串以 0x 或 0X 开头 → 十六进制(如 "0x1A" 转换为 26);
- 字符串以 0 开头(非 0x)→ 八进制(如 "012" 转换为 10);
- 其他情况 → 十进制(如 "123" 转换为 123)。
base = 2 - 36(指定进制):仅识别该进制下的有效字符(09、az/A~Z,其中 a/A 代表 10,b/B 代表 11,…,z/Z 代表 35)。例如:base=16 时,"1A" 转换为 26;base=2 时,"1010" 转换为 10。
3.endptr 的用法
endptr 用于标记转换终止的位置,方便处理 “字符串中包含数字和非数字” 的场景。例如:转换 "123abc" 时,*endptr 会指向 'a'(第一个未转换的字符)。
五、示例代码
- 基本用法(十进制转换)
#include <stdio.h>
#include <stdlib.h>int main()
{const char *str = "12345";char *end;long num = strtol(str, &end, 10); // 十进制转换printf("转换结果:%ld\n", num); // 输出:12345printf("未转换的字符:%s\n", end); // 输出:(空,因全部转换)return 0;
}
- 示例 2:自动判断进制(base=0)
#include <stdio.h>
#include <stdlib.h>int main()
{const char *str1 = "0x1A"; // 十六进制(0x前缀)const char *str2 = "012"; // 八进制(0前缀)const char *str3 = "123"; // 十进制(无特殊前缀)long num1 = strtol(str1, NULL, 0);long num2 = strtol(str2, NULL, 0);long num3 = strtol(str3, NULL, 0);printf("0x1A → %ld\n", num1); // 输出:26(16×1 + 10 = 26)printf("012 → %ld\n", num2); // 输出:10(8×1 + 2 = 10)printf("123 → %ld\n", num3); // 输出:123return 0;
}
- 示例 3:使用 endptr 处理混合字符串
#include <stdio.h>
#include <stdlib.h>int main()
{const char *str = "123abc456";char *end;long num = strtol(str, &end, 10); // 转换到第一个非数字字符 'a' 停止printf("转换结果:%ld\n", num); // 输出:123printf("未转换的部分:%s\n", end); // 输出:abc456return 0;
}
- 示例 4:错误处理(溢出和无效转换)
#include <stdio.h>
#include <stdlib.h>
#include <errno.h> // 用于查看 errnoint main()
{// 测试溢出(假设 LONG_MAX 为 9223372036854775807)const char *str1 = "9223372036854775808"; // 超过 LONG_MAXlong num1 = strtol(str1, NULL, 10);if (errno == ERANGE) {printf("str1 转换溢出:%ld\n", num1); // 输出:9223372036854775807(LONG_MAX)}// 测试无效转换(无有效数字)const char *str2 = "abc123";long num2 = strtol(str2, NULL, 10);printf("str2 转换结果:%ld\n", num2); // 输出:0(无有效数字)return 0;
}