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

如何在C语言中实现带可选0x前缀的十六进制字符串转十进制?

十六进制字符串转整数(htoi)的前缀处理实现

针对你在《The C Programming Language》练习2.3中遇到的0x/0X前缀处理问题,我们可以通过以下步骤优化代码,同时简化实现逻辑:

核心思路

  1. 前缀判断:先检查字符串开头是否存在可选的0x或0X前缀,若存在则跳过这两个字符,从第三个字符开始处理。
  2. 简化数值计算:无需反转字符串,直接从左到右遍历累积计算——每一步将当前结果乘以16,再加上当前字符对应的十六进制值,逻辑更直观且节省内存。
  3. 修正合法性校验:校验时要排除前缀的0和x/X,只校验前缀之后的字符(无前缀则校验全部)。

修改后的完整代码

#include <stdio.h>
#include <string.h>
#include <ctype.h>

// 校验十六进制字符串合法性(支持0x/0X前缀)
int check_valid(char *s) {
    int len = strlen(s);
    int start = 0;

    // 跳过可选前缀
    if (len >= 2 && s[0] == '0' && (tolower(s[1]) == 'x')) {
        start = 2;
        // 前缀后无字符的情况直接判定无效
        if (start >= len) return 0;
    }

    // 校验剩余字符
    for (int i = start; i < len; i++) {
        if (!isdigit(s[i]) && !(tolower(s[i]) >= 'a' && tolower(s[i]) <= 'f')) {
            return 0;
        }
    }
    return 1;
}

// 单个十六进制字符转对应整数值
int rawint(char c) {
    if (isalpha(c)) {
        return toupper(c) - 'A' + 10;
    } else {
        return c - '0';
    }
}

// 十六进制字符串转整数,处理0x/0X前缀
int htoi(char *s) {
    int len = strlen(s);
    int dec = 0;
    int start = 0;

    // 跳过前缀
    if (len >= 2 && s[0] == '0' && (tolower(s[1]) == 'x')) {
        start = 2;
    }

    // 从左到右累积计算
    for (int i = start; i < len; i++) {
        dec = dec * 16 + rawint(s[i]);
    }

    return dec;
}

int main() {
    // 测试用例:带前缀、不带前缀、大写前缀都可以
    char s1[] = "7abc";
    char s2[] = "0x7abc";
    char s3[] = "0X1A3F";
    char s4[] = "0x"; // 无效用例

    // 测试s1
    if (check_valid(s1)) {
        printf("%s -> %d\n", s1, htoi(s1));
    } else {
        printf("%s 无效\n", s1);
    }

    // 测试s2
    if (check_valid(s2)) {
        printf("%s -> %d\n", s2, htoi(s2));
    } else {
        printf("%s 无效\n", s2);
    }

    // 测试s3
    if (check_valid(s3)) {
        printf("%s -> %d\n", s3, htoi(s3));
    } else {
        printf("%s 无效\n", s3);
    }

    // 测试s4
    if (check_valid(s4)) {
        printf("%s -> %d\n", s4, htoi(s4));
    } else {
        printf("%s 无效\n", s4);
    }

    return 0;
}

关键修改点说明

  1. 前缀处理:在check_valid和htoi函数中,都先判断字符串长度是否≥2,且前两个字符是0x或0X,如果是就将起始索引设为2,跳过前缀。
  2. 移除反转逻辑:原来的reverse函数完全不需要,通过dec = dec * 16 + rawint(s[i])的方式,直接从左到右计算十六进制值,逻辑更简洁且避免了动态内存分配的开销。
  3. 合法性校验优化:校验时跳过前缀后,若剩余无字符(比如单独的0x)直接返回无效;同时用tolower统一处理大小写,减少重复判断。
  4. 测试用例扩展:新增了带前缀、大写前缀、无效前缀的测试用例,覆盖更多场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:55:36