当前位置: 首页 > 新闻动态 > 网络资讯

C++ 怎么实现各种进制转换 C++ bitset与stringstream转换技巧【工具】

作者:尼克 浏览: 发布日期:2026-02-01
[导读]:C++进制转换优先用std::bitset处理固定位宽二进制、stringstream处理8/10/16进制字符串互转;bitset模板参数须编译期常量,调用to_string()获取字符串,自动高位补零。
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",不需要手动 pad

std::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::uppercasess → "FF"

转任意进制(如 3、7、36)只能手写

bitsetstringstream 都不支持。必须自己实现除基取余,尤其注意负数处理。

  • 正数直接循环取余,倒序拼接;负数建议先转为无符号类型再算,避免右移符号扩展干扰
  • 基数 >10 时需映射数字到字符:0–9、a–z(最多到 36 进制),别忘了大小写控制
  • 常见坑: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 字节)。

  • 不要在 tight loop 里反复创建 stringstream 对象,可复用并调用 ss.str("")ss.clear() 重置
  • std::stoi/std::stol 支持进制参数,比 stringstream 简洁,但异常处理更重(抛 std::invalid_argumentstd::out_of_range

  • 所有字符串转整数操作,都需检查是否转换完整:用 std::strtolendptrstringstream::eof(),否则 "123abc" 会被当成 123 静默接受

真正麻烦的从来不是“怎么转”,而是“边界怎么控”——负数、溢出、前缀、空格、不完整输入,这些地方一漏,线上就出隐蔽 bug。

免责声明:转载请注明出处:http://shjed.com/news/794273.html

扫一扫高效沟通

多一份参考总有益处

免费领取网站策划SEO优化策划方案

请填写下方表单,我们会尽快与您联系
感谢您的咨询,我们会尽快给您回复!