




C++进制转换优先用std::bitset处理固定位宽二进制、stringstream处理8/10/16进制字符串互转;bitset模板参数须编译期常量,调用to_string()获取字符串,自动高位补零。
直接说结论:C++ 里进制转换别硬写循环,优先用 std::bitset 处理固定位宽的二进制,用 std::stringstream + std::hex/std::oct 做整数与字符串间的任意进制互转;但要注意 stringstream 不支持直接转任意进制(比如转 3 进制),bitset 只支持 2 进制且长度必须编译期确定。
std::bitset 转二进制字符串最稳适合把一个整数(≤64 位)快速转成固定长度的二进制字符串,比如调试寄存器、生成掩码。
bitset 构造时传入整数,它会自动按补码截断填充,例如 std::bitset(255) 得到 "11111111",std::bitset(-1) 也是 "11111111"(因为 -1 补码就是全 1)int n = 16; std::bitset(x) 是非法的 —— 模板参数必须是常量表达式.to_string(),不是 .c_str()(它没这个方法)std::bitset(5) → "0000000000000101",不需要手动 padstd::stringstream 转 8/10/16 进制字符串这是标准库最通用的整数 ↔ 字符串进制转换方式,但只内置支持八、十、十六进制。
int x = 255; std::stringstream ss; ss << std::hex << x; // 小写十六进制 → "ff" ss.str(); // 得到字符串 // 同理:std::oct → 八进制,std::dec → 十进制(默认)
failbit 被置位ss >> std::hex >> y 会跳过前导空格,但不跳过 0x 前缀 —— 如果字符串带 "0xff",得先去掉前缀或用 std::stoi(str, nullptr, 16)
std::uppercase:ss → "FF"
bitset 和 stringstream 都不支持。必须自己实现除基取余,尤其注意负数处理。
0 输入必须单独处理,否则循环不进,结果为空字符串std::string to_base(int n, int base) {
if (n == 0) return "0";
bool neg = n < 0;
unsigned int un = neg ? -n : n; // 防止 INT_MIN 取负溢出,应改用 long long 或 uint64_t
std::string res;
while (un) {
int r = un % base;
res += (r < 10) ? '0' + r : 'a' + r - 10;
un /= base;
}
if (neg) res += '-';
std::reverse(res.begin(), res.end());
return res;
}频繁转换时,stringstream 构造/析构开销比纯算法大;bitset 零拷贝但内存占用固定(如 bitset 占 128 字节)。
stringstream 对象,可复用并调用 ss.str("") 和 ss.clear() 重置std::stoi/std::stol 支持进制参数,比 stringstream 简洁,但异常处理更重(抛 std::invalid_argument 或 std::out_of_range
std::strtol 的 endptr 或 stringstream::eof(),否则 "123abc" 会被当成 123 静默接受真正麻烦的从来不是“怎么转”,而是“边界怎么控”——负数、溢出、前缀、空格、不完整输入,这些地方一漏,线上就出隐蔽 bug。