c++如何将hex字符串转为int_c++十六进制转换【示例】

std::stoi转hex最简单但需指定base=16或0,支持大小写和"0x"前缀;非法字符抛异常,尾部垃圾被忽略;超int范围须用std::stoul/stoull,严格校验需std::strtol配合endptr。

std::stoi 直接转 hex 字符串最简单

只要字符串是标准格式(如 "FF""0x1A""fF"),std::stoi 是最快捷的选择。它支持自动识别前缀("0x""0X"),也支持大小写混合的十六进制字符。

关键点:必须显式传入 base = 16,否则默认按十进制解析;如果含 "0x" 前缀,std::stoi 会自动跳过,但前提是 base 设为 016 —— 更稳妥的做法是统一用 16 并确保输入不含前缀,或统一带前缀后设 base = 0

std::string s = "0xFF";
int x = std::stoi(s, nullptr, 0); // base=0 → 自动识别前缀
// 或
s = "FF";
x = std::stoi(s, nullptr, 16); // 明确 base=16,不依赖前缀
  • 抛异常:输入非法(如 "G1")时抛 std::invalid_argument;溢出时抛 std::out_of_range
  • 不检查尾部垃圾字符:"FFabc" 会被静默转成 255stoi 只读到第一个非法字符为止
  • 只适用于 int 范围(通常是 32 位有符号),超范围会溢出报错

需要更严格解析?用 std::strtol 控制细节

std::strtol 是 C 风格函数,但控制力更强,适合需验证完整字符串、处理长整型、或兼容旧编译器的场景。它返回 long,并用 endptr 指出解析停在哪——这是判断是否“全字符串有效”的核心。

const char* s = "1A3F";
char* end;
long x = std::strtol(s, &end, 16);
if (*end != '\0') {
    // 解析未覆盖整个字符串,例如 "1A3FG" 或 "1A3F "
}
  • base = 0 同样支持自动识别 "0x" 前缀;base = 16 则忽略前缀,把 "0xFF" 当作非法(因为 '0' 不是合法 hex 字符)
  • 返回值类型是 long,在 64 位系统上常为 64 位,但仍是带符号类型;若需无符号或更大范围,考虑 std::strtoulstd::stoul
  • 注意 endptr 必须非空,且调用后要检查是否走到末尾,否则无法区分 "FF""FFxx"

处理大写/小写、空格、前缀混杂?先预处理再转

标准转换函数不自动 trim 空格,也不强制大小写归一化。如果输入可能含首尾空格、大小写混用、甚至多余前缀(如 " 0x AbC "),直接转容易失败或误读。

立即学习“C++免费学习笔记(深入)”;

安全做法是手动清洗:

std::string clean_hex(const std::string& s) {
    std::string out;
    for (char c : s) {
        if (std::isxdigit(c)) out += std::tolower(c);
    }
    return out;
}
// 使用:
std::string raw = " 0x AbC ";
int x = std::stoi(clean_hex(raw), nullptr, 16); // → 2748
  • 不要依赖 std::isspace + erase 做 trim,因为 hex 字符串中间不该有空格;真正要的是“只留 0-9 a-f A-F”
  • std::tolower 安全处理非字母字符,可直接对整个字符串调用
  • 如果原始字符串必须保留语义(如错误定位),那就别清洗,改用 strtol + endptr 定位非法位置

超 32 位或需无符号?换用 std::stoul / std::stoull

当 hex 字符串表示的值超过 INT_MAX(如 "FFFFFFFF" 在 32 位系统上是 4294967295,已超出

int 正数范围),必须用无符号类型转换函数,否则抛 std::out_of_range

  • std::stoulunsigned long(至少 32 位)
  • std::stoullunsigned long long(至少 64 位),推荐用于任意长度 hex 字符串
  • 它们的行为和 stoi 几乎一致:同样支持 base=016,同样抛异常,同样忽略尾部无效字符
  • 示例:std::stoull("FFFFFFFFFFFFFFFF", nullptr, 16) 在支持的平台上能正确返回 18446744073709551615

真正容易被忽略的是:即使你声明了 uint64_t x,如果用 std::stoi 赋值,转换过程已在 int 范围内截断或报错——类型声明不改变转换函数本身的语义。