c语言16进制转换10进制

99ANYc3cd6
预计阅读时长 18 分钟
位置: 首页 C语言 正文

使用标准库函数 strtol (推荐)

这是最简单、最安全、也是最常用的方法。strtol 函数可以将一个字符串表示的数字转换为长整型(long),并可以指定转换的基数(进制)。

函数原型

long strtol(const char *nptr, char **endptr, int base);

参数说明

  • nptr: 指向要转换的字符串的指针。
  • endptr: 一个指向 char* 类型的指针,如果这个指针不是 NULL,函数会在这个指针中存储转换停止后的位置,这对于检查字符串中是否有非法字符非常有用。
  • base: 转换的基数(进制)。
    • base0,函数会根据字符串的前缀自动判断进制:
      • 0x0X 开头 -> 16进制
      • 0 开头 -> 8进制 (Octal)
      • 其他 -> 10进制 (Decimal)
    • base16,则直接将字符串当作16进制处理。
    • base 的取值范围是 0 或 2 到 36。

示例代码

#include <stdio.h>
#include <stdlib.h> // 必须包含此头文件才能使用 strtol
#include <errno.h>  // 用于检查转换错误
int main() {
    const char *hex_str1 = "1A3F";  // 没有0x前缀
    const char *hex_str2 = "0x7B";  // 有0x前缀
    const char *hex_str3 = "G12";   // 包含非法字符G
    char *endptr; // 用于存放转换结束后的位置
    long decimal_num;
    // --- 示例1:转换没有0x前缀的16进制字符串 ---
    // 将base设为16,明确告诉函数这是16进制
    decimal_num = strtol(hex_str1, &endptr, 16);
    // 检查转换是否成功
    if (errno == ERANGE) {
        printf("错误:数字超出long的范围,\n");
    } else if (endptr == hex_str1) {
        printf("错误:没有数字被转换,\n");
    } else {
        printf("字符串 \"%s\" 转换为10进制是: %ld\n", hex_str1, decimal_num);
    }
    // --- 示例2:转换有0x前缀的16进制字符串 ---
    // 将base设为0,让函数自动识别前缀
    decimal_num = strtol(hex_str2, &endptr, 0);
    if (errno == ERANGE) {
        printf("错误:数字超出long的范围,\n");
    } else if (endptr == hex_str2) {
        printf("错误:没有数字被转换,\n");
    } else {
        printf("字符串 \"%s\" 转换为10进制是: %ld\n", hex_str2, decimal_num);
    }
    // --- 示例3:处理包含非法字符的字符串 ---
    decimal_num = strtol(hex_str3, &endptr, 16);
    if (errno == ERANGE) {
        printf("错误:数字超出long的范围,\n");
    } else if (endptr == hex_str3) {
        printf("错误:没有数字被转换,\n");
    } else {
        // strtol会转换到第一个非法字符为止
        printf("字符串 \"%s\" 转换到 \"%s\" 时停止,转换结果是: %ld\n", hex_str3, endptr, decimal_num);
    }
    return 0;
}

输出结果:

字符串 "1A3F" 转换为10进制是: 6719
字符串 "0x7B" 转换为10进制是: 123
字符串 "G12" 转换到 "12" 时停止,转换结果是: 0

手动实现转换算法

如果你需要理解转换的原理,或者在没有标准库的环境下进行开发,可以手动实现这个算法,16进制转10进制的原理是按权展开求和

对于一个16进制数 1A3F,其10进制值为: 1 * 16³ + A * 16² + 3 * 16¹ + F * 16⁰ = 1 * 4096 + 10 * 256 + 3 * 16 + 15 * 1 = 4096 + 2560 + 48 + 15 = 6719

算法步骤

  1. 初始化一个结果变量 decimal_value 为 0。
  2. 初始化一个权重变量 power 为 1 (代表 16⁰)。
  3. 从16进制数的最后一位开始向前遍历。
  4. 对于每一位字符: a. 将字符转换为对应的数值('A' -> 10, 'F' -> 15, '9' -> 9)。 b. 将该数值乘以当前的权重 power。 c. 将结果累加到 decimal_value 中。 d. 将权重 power 乘以 16,为下一位做准备。
  5. 遍历结束后,decimal_value 就是最终的10进制结果。

示例代码

#include <stdio.h>
#include <ctype.h> // 用于 isxdigit 和 toupper
// 辅助函数:将单个16进制字符转换为对应的数值
int hexCharToValue(char c) {
    c = toupper(c); // 统一转为大写,简化判断
    if (c >= '0' && c <= '9') {
        return c - '0';
    } else if (c >= 'A' && c <= 'F') {
        return 10 + (c - 'A');
    }
    // 如果字符非法,返回-1
    return -1;
}
// 手动函数:将16进制字符串转换为10进制整数
long hexToDecimal(const char *hex_str) {
    long decimal_value = 0;
    long power = 1; // 16的幂次,从16^0开始
    // 从字符串末尾向前遍历
    for (int i = strlen(hex_str) - 1; i >= 0; i--) {
        char c = hex_str[i];
        // 检查字符是否为有效的16进制字符
        if (!isxdigit(c)) {
            printf("错误:字符 '%c' 不是有效的16进制数,\n", c);
            return -1; // 返回-1表示错误
        }
        int value = hexCharToValue(c);
        decimal_value += value * power;
        power *= 16;
    }
    return decimal_value;
}
int main() {
    const char *hex_str1 = "1A3F";
    const char *hex_str2 = "FF";
    const char *hex_str3 = "12G"; // 包含非法字符
    long result1 = hexToDecimal(hex_str1);
    if (result1 != -1) {
        printf("手动转换: 字符串 \"%s\" 转换为10进制是: %ld\n", hex_str1, result1);
    }
    long result2 = hexToDecimal(hex_str2);
    if (result2 != -1) {
        printf("手动转换: 字符串 \"%s\" 转换为10进制是: %ld\n", hex_str2, result2);
    }
    long result3 = hexToDecimal(hex_str3);
    if (result3 != -1) {
        printf("手动转换: 字符串 \"%s\" 转换为10进制是: %ld\n", hex_str3, result3);
    }
    return 0;
}

输出结果:

手动转换: 字符串 "1A3F" 转换为10进制是: 6719
手动转换: 字符串 "FF" 转换为10进制是: 255
错误:字符 'G' 不是有效的16进制数。

总结与对比

特性 方法一: strtol 方法二: 手动实现
易用性 非常高,一行代码即可完成。 较低,需要编写较多代码。
健壮性 非常高,能正确处理前缀、非法字符、溢出等情况。 较低,需要自己处理各种边界条件和错误。
性能 通常非常快,由标准库高度优化。 取决于实现,但一般不如库函数。
适用场景 绝大多数实际应用场景,推荐首选。 学习目的、嵌入式系统、或需要特殊逻辑时。
依赖 需要包含 <stdlib.h> 只需要基本的标准库,如 <stdio.h>, <ctype.h>

在日常编程中,强烈推荐使用 strtol 函数,因为它简单、安全、可靠,手动实现的方法虽然有助于理解底层原理,但在生产代码中不推荐使用,因为它容易出错且维护成本高。

-- 展开阅读全文 --
头像
C语言char转int的具体方法是什么?
« 上一篇 03-24
c语言ascii码转换字符
下一篇 » 03-24
取消
微信二维码
支付宝二维码

目录[+]