You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求修正十六进制转十进制程序:需手动实现转换而非调用库函数

手动实现十六进制转十进制的修正方案

你的代码已经完成了输入验证和错误检查的部分,现在只需要替换掉strtoull库函数,用手动计算的方式实现十六进制到十进制的转换。下面是修正后的完整代码,以及关键逻辑的解释:

#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h> // 用于溢出检查,可选

#define SIZE 20

// 手动实现十六进制转十进制
unsigned long long hex_to_dec(const char *hex_str) {
    unsigned long long result = 0;
    // 跳过可选的0x或0X前缀
    if (hex_str[0] == '0' && (hex_str[1] == 'x' || hex_str[1] == 'X')) {
        hex_str += 2;
    }
    while (*hex_str != '\0') {
        int digit;
        char c = *hex_str;
        if (isdigit(c)) {
            digit = c - '0';
        } else if (isupper(c)) {
            digit = c - 'A' + 10;
        } else if (islower(c)) {
            digit = c - 'a' + 10;
        } else {
            // 理论上不会触发,因为前面已验证是合法十六进制字符
            return 0;
        }
        // 可选:溢出检查,防止超出unsigned long long最大值
        if (result > ULLONG_MAX / 16 || (result * 16 > ULLONG_MAX - digit)) {
            printf("警告:数值超出范围,可能溢出\n");
            return ULLONG_MAX;
        }
        result = result * 16 + digit;
        hex_str++;
    }
    return result;
}

int main(void) {
    system("chcp 1251");
    char str[SIZE][SIZE], (*pstr)[SIZE];
    pstr = str;
    char* pcode;
    int kst;
    printf("请输入要转换的十六进制数的行数:");
    scanf_s("%d", &kst);
    getchar();
    while (kst > SIZE) {
        printf("超出允许范围(行数必须小于20):");
        scanf_s("%d", &kst);
        getchar();
    }
    while (kst < 1) {
        printf("输入的数值太小,请输入1到20之间的数:");
        scanf_s("%d", &kst);
        getchar();
    }

    printf("\n请输入十六进制数:\n\n");

    while (pstr < str + kst) {
        gets_s(*pstr);
        // 验证是否为合法十六进制字符
        int is_valid = 1;
        for (pcode = *pstr; *pcode != '\0'; pcode++) {
            if (!isxdigit((unsigned char)*pcode)) {
                **pstr = '\0'; // 标记为无效输入
                is_valid = 0;
                break;
            }
        }
        pstr++;
    }

    printf("\n转换结果\n");

    unsigned long long decimal;
    for (pstr = str; pstr < str + kst; pstr++) {
        if (**pstr == '\0') {
            printf("十六进制:输入错误!\n");
        } else {
            decimal = hex_to_dec(*pstr);
            printf("十六进制:%#020llx | 十进制:%llu\n", decimal, decimal);
        }
    }
    return 0;
}

关键逻辑说明

  1. hex_to_dec函数核心:

    • 先处理十六进制的0x/0X前缀,兼容带前缀的输入格式
    • 逐个字符映射:将字符转换为0-15的数值(数字直接转,字母按大小写对应10-15)
    • 累加计算:通过result = result * 16 + digit实现转换——十六进制每一位的权重是前一位的16倍,比如0x1A就是1*16 + 10 = 26
    • 可选溢出检查:避免数值超出unsigned long long的存储范围
  2. 原代码的保留与优化:

    • 保留了你原本的输入行数验证、十六进制字符合法性检查逻辑
    • 把模糊的isXDigit变量替换为更清晰的is_valid,明确标记无效输入

注意事项

  • 如果输入的十六进制数超过unsigned long long的最大值(0xFFFFFFFFFFFFFFFF),会触发溢出警告,新手可以暂时注释掉溢出检查部分,先专注于转换逻辑的理解
  • 代码中使用的scanf_s和gets_s是微软编译器的安全输入函数,若使用GCC等编译器,可替换为scanf和fgets(注意fgets会读取换行符,需额外处理)

内容的提问来源于stack exchange,提问作者dan1chX

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:40:27