网站首页 > java教程 正文
核心定位
strtoll 是C语言中用于将字符串转换为长长整型(long long)的「多进制翻译官」,它能将数字字符串(如 "123"、"0xFF"、"077")转换为 long long 类型的整数,支持2到36进制。就像一位精通多国语言的翻译,它能理解不同进制的「数字语言」,还能告诉你翻译到哪里结束!
函数原型与参数
long long strtoll(const char *str, char **endptr, int base);
- 入口参数:
- str:指向待转换字符串的指针
- endptr:指向 char* 的指针,用于存储转换结束的位置
- 智能跳过:自动忽略字符串前的空白符(空格、Tab等)
- 停止条件:遇到第一个非法字符(含字符串结尾的\0)立即停止
- base:进制(2到36)
- 特殊规则:
- 0:自动检测进制(0x 开头为16进制,0 开头为8进制,否则为10进制)
- 16:支持 0x 或 0X 前缀
- 返回参数:
- 成功转换:返回对应的长长整型值
- 无效输入:返回 0LL,并将 endptr 指向原字符串
- 溢出风险:若数值超出 long long 范围,返回 LLONG_MAX 或 LLONG_MIN,并设置 errno 为 ERANGE
实战代码演示
场景1 基础转换
#include
#include
int main() {
const char *num_str = "1234567890123456789";
char *endptr;
long long num = strtoll(num_str, &endptr, 10); // 转换字符串
printf("转换结果:%lld\n", num); // 输出:1234567890123456789
printf("转换结束位置:'%s'\n", endptr); // 输出:''(空字符串)
return 0;
}
场景2 多进制支持
#include
#include
int main() {
const char *hex_str = "0xFF"; // 16进制
char *endptr;
long long hex_num = strtoll(hex_str, &endptr, 0); // 自动检测进制
printf("16进制转换结果:%lld\n", hex_num); // 输出:255
const char *bin_str = "1010"; // 2进制
long long bin_num = strtoll(bin_str, &endptr, 2); // 2进制转换
printf("2进制转换结果:%lld\n", bin_num); // 输出:10
return 0;
}
场景3 错误处理
#include
#include
int main() {
const char *invalid_str = "hello";
char *endptr;
long long result = strtoll(invalid_str, &endptr, 10); // 转换字符串
printf("无效输入结果:%lld\n", result); // 输出:0
printf("转换结束位置:'%s'\n", endptr); // 输出:'hello'
return 0;
}
四大致命陷阱
陷阱 | 后果 | 防御方案 |
未检查endptr | 无法检测部分转换 | 检查 endptr 是否指向字符串结尾 |
未处理溢出 | 程序行为不可预测 | 检查 errno 是否为 ERANGE |
忽略后置字符 | 潜在数据污染风险 | 检查字符串剩余部分是否合法 |
空指针崩溃 | 程序直接崩溃 | 使用前必须检查指针是否为NULL |
增强版安全用法
封装安全转换函数
#include
#include
#include
long long safe_strtoll(const char *str, int base) {
if (str == NULL) {
fprintf(stderr, "输入指针为NULL!\n");
return 0LL;
}
char *endptr;
long long num = strtoll(str, &endptr, base); // 使用strtoll检测错误
// 检查是否整个字符串都被转换
if (*endptr != '\0') {
fprintf(stderr, "警告:'%s' 含非数字字符\n", endptr);
}
// 检查是否溢出
if (errno == ERANGE) {
fprintf(stderr, "错误:数值超出long long范围!\n");
return 0LL;
}
return num;
}
int main() {
printf("安全转换结果:%lld\n", safe_strtoll("9223372036854775807", 10)); // 正常
printf("安全转换结果:%lld\n", safe_strtoll("9223372036854775808", 10)); // 触发溢出警告
return 0;
}
对比strtoll与atoll
特性 | strtoll | atoll |
错误检测 | 通过endptr和errno | 只能返回0 |
溢出处理 | 返回LLONG_MAX/MIN | 未定义行为 |
灵活性 | 支持2-36进制 | 仅十进制 |
使用复杂度 | 需额外参数检查 | 一行代码搞定 |
黄金法则
- 复杂场景用strtoll:需要错误检测、溢出处理或多进制转换时
- 检查endptr:确保字符串被完整转换,避免部分转换导致逻辑错误
- 防御性检查:
- 转换前检查指针是否为 NULL
- 转换后检查字符串剩余部分是否合法
- 替代方案:C++中推荐使用 std::stoll,Python用 int(),Java用 Long.parseLong()
脑洞应用:超大整数计算
#include
#include
int main() {
const char *num1_str = "9223372036854775807"; // LLONG_MAX
const char *num2_str = "1000000000000000000";
long long num1 = strtoll(num1_str, NULL, 10);
long long num2 = strtoll(num2_str, NULL, 10);
// 计算差值
long long diff = num1 - num2;
printf("差值:%lld\n", diff); // 输出:差值:8223372036854775807
return 0;
}
strtoll 如同一位多进制翻译官——不仅能翻译数字,还能告诉你翻译到哪里结束。掌握它的特性后,让你的程序在数字世界中游刃有余!
猜你喜欢
- 2025-03-20 Java内存泄漏和CPU飙高问题排查全流程
- 2025-03-20 线上问题解决:java的CPU100%问题分析,定位及解决
- 2025-03-20 字节一面-如何实现短链接转换服务
- 2025-03-20 JVM超神之路:年后跳槽需要的JVM知识点,都给你整理好了
- 2025-03-20 深入了解SHA-256算法及其Java实现
- 2025-03-20 Java程序性能调优步骤(java性能调优从哪几个方面入手)
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)