C++怎么转换十六进制 C++数值转hex字符串【总结】

5次阅读

C++怎么转换十六进制 C++数值转hex字符串【总结】

std::Stringstream 怎么转 int 到 hex 字符串(带前缀)

直接用 std::hexstd::showbase 最省事,但默认不补零、不转大写,且容易漏掉 std::uppercasestd::setw 配合 std::setfill

  • 要输出 "0xFF":必须加 std::showbase,否则只有 "FF"
  • 要固定 2 位(如 "0x0F"):得用 std::setw(2) + std::setfill('0'),且 setw 只对下一个输出项生效
  • 十六进制字母默认小写,加 std::uppercase 才变大写

示例:

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

int x = 15; std::stringstream ss; ss << std::hex << std::showbase << std::uppercase << std::setw(2) << std::setfill('0') << x; std::string s = ss.str(); // 得到 "0x0F"

std::formatc++20)怎么安全生成 hex 字符串

std::format 更简洁、类型安全,但要注意编译器支持和格式说明符写法 —— 它不认 std::hex 这类流操纵符,得用格式字符串。

  • {:x} → 小写无前缀("ff"
  • {:#x} → 小写带 0x"0xff"
  • {:#X} → 大写带 0X"0XFF"
  • 补零要用 {:02x}{:#04x}:数字表示总宽度,0 表示用 0 填充

示例:

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

std::string s = std::format("{:#04x}", 15); // "0x0f" std::string t = std::format("{:#04X}", 255); // "0XFF"

注意:std::format 在 GCC 13+ / Clang 15+ 默认可用,MSVC 2022 17.5+ 支持;若编译失败,先确认是否开了 -std=c++20 且标准库完整。

为什么 sprintf / snprintf 不推荐用于 C++ 字符串转换

不是不能用,而是容易踩缓冲区溢出、类型不匹配、无符号整数截断三连坑。

  • sprintf(buf, "%x", -1) → 输出大量 "ffffffff"(有符号转无符号解释),但没报错
  • snprintf 要手动管理 buf 大小,std::string.data() 在 C++20 前还不能直接当可写缓冲区用
  • 格式符和参数类型不一致(比如用 %xlong long)会触发未定义行为,编译器不一定警告

除非在嵌入式等极度受限环境,否则优先用 std::stringstreamstd::format

unsigned char 数组怎么转 hex 字符串(如二进制 dump 场景)

这是最常被低估的场景:逐字节转两位 hex,还要避免符号扩展导致高位全 F。

  • 直接对 unsigned charstd::hex 没问题,但若误写成 char,负值会被提升为 int(如 0xFF 变成 -1 → 升级为 0xFFFFFFFF → 输出 "ffffffff"
  • 推荐显式转 unsigned intstatic_cast<unsigned int>(b)</unsigned>,再格式化
  • 循环中别反复构造 std::stringstream,可复用一个对象并调用 .str("") 清空

示例(安全转 4 字节):

unsigned char data[] = {0x0a, 0xff, 0x80, 0x00}; std::stringstream ss; for (unsigned char b : data) {     ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<unsigned int>(b); } std::string hex_str = ss.str(); // "0aff8000"

真正麻烦的是边界对齐、分组空格、大小端隐含假设——这些不在基础转换里,但一旦需求出现,就不再是“转个 hex”那么简单了。

text=ZqhQzanResources