std::to_string 是 C++11 起最快最安全的 unsigned long 转字符串方式,无需 <sstream>,线程安全且自动适配平台位宽;需格式化时优先用 C++20 std::format,兼容旧标准则用 std::ostringstream;禁用非标的 itoa/ultoa。

用 std::to_string 最快最安全
直接调用 std::to_string 是 C++11 起最推荐的方式,它原生支持 unsigned long,无需手动处理进制或缓冲区。
注意:不同平台下 unsigned long 的位宽可能不同(Linux x64 是 64 位,Windows MSVC 是 32 位),但 std::to_string 会自动适配,不会截断。
示例:
unsigned long val = 1234567890UL; std::string s = std::to_string(val); // 结果 "1234567890"
- 不依赖
<sstream>,头文件只需<string> - 线程安全,无静态缓冲区风险
- 不能控制格式(比如补零、十六进制),有这类需求就得换方法
需要格式化时用 std::format(C++20)
如果你要转成十六进制、带前导零,或者对齐宽度,std::format 是目前最现代、类型安全的选择。
立即学习“C++免费学习笔记(深入)”;
示例:
unsigned long x = 255;
std::string hex = std::format("{:x}", x); // "ff"
std::string padded = std::format("{:08x}", x); // "000000ff"
std::string dec = std::format("{}", x); // "255"(等价于 to_string)
- 需编译器支持 C++20(GCC 13+、Clang 15+、MSVC 19.30+)
- 不支持 C++17 及更早版本;别误用
fmt::format当标准库——那是第三方库 - 比
std::ostringstream性能更好,且无运行时格式字符串解析开销
兼容老标准(C++11/14)且要格式化?用 std::ostringstream
当项目卡在 C++11/14,又必须输出十六进制、八进制或补零时,std::ostringstream 是稳妥选择。
示例:
#include <sstream>
#include <iomanip>
unsigned long n = 1000;
std::ostringstream oss;
oss << std::hex << n; // 小写十六进制
std::string s = oss.str(); // "3e8"
oss.str(""); // 清空内容
oss << std::setfill('0') << std::setw(8) << std::hex << n;
s = oss.str(); // "000003e8"
- 务必调用
oss.str("")或构造新对象来清空,重复使用同一ostringstream会追加而非覆盖 -
std::setw是一次性的,每输出一项都要重设 - 性能比
std::to_string和std::format差,因为涉及流状态管理和内存动态分配
绝对不要用 itoa 或 ultoa
这两个函数不是标准 C++,是某些 C 库(如 MSVC CRT)的扩展,Linux GCC 默认不提供,跨平台项目中用了等于埋雷。
常见错误现象:
- 编译报错:
'itoa' was not declared in this scope - 即使编译通过,在 Clang/Linux 下链接失败
- 参数顺序不统一(
itoa第三个参数是进制,ultoa在某些实现里没有该参数)
替代方案始终优先选标准库:用 std::to_string、std::format 或 std::ostringstream。
真正容易被忽略的是 unsigned long 在不同 ABI 下的宽度差异——它会影响字符串长度上限,但不影响转换逻辑本身;只要你不把结果存进固定大小的 char[10] 数组,就不用手动算位数。


















