专业的JAVA编程教程与资源

网站首页 > java教程 正文

C语言strtoll函数详解:字符串到长长整型的「多进制翻译官

temp10 2025-03-20 19:02:51 java教程 5 ℃ 0 评论

核心定位

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;
}

四大致命陷阱

陷阱

 C语言strtoll函数详解:字符串到长长整型的「多进制翻译官

后果

防御方案

未检查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进制

仅十进制

使用复杂度

需额外参数检查

一行代码搞定


黄金法则

  1. 复杂场景用strtoll:需要错误检测、溢出处理或多进制转换时
  2. 检查endptr:确保字符串被完整转换,避免部分转换导致逻辑错误
  3. 防御性检查
  • 转换前检查指针是否为 NULL
  • 转换后检查字符串剩余部分是否合法
  1. 替代方案: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 如同一位多进制翻译官——不仅能翻译数字,还能告诉你翻译到哪里结束。掌握它的特性后,让你的程序在数字世界中游刃有余!

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表