数值格式化
1、整数格式化
std::format("{:格式说明符}", 整数值);
格式说明符: [[fill]align][sign]["#"]["0"][width]["." precision][type]
整数不支持 precision(小数点后位数,指定会编译错误
常用进制
| 分类 |
选项 |
说明 |
示例(值 = 42) |
输出 |
| 进制类型 (type) |
d |
十进制(默认) |
{:d} |
42 |
|
b |
二进制(无前缀) |
{:b} |
101010 |
|
B |
二进制(大写,无前缀) |
{:B} |
101010 |
|
o |
八进制(无前缀) |
{:o} |
52 |
|
x |
十六进制(小写,无前缀) |
{:x} |
2a |
|
X |
十六进制(大写,无前缀) |
{:X} |
2A |
|
(空) |
默认十进制 |
{} |
42 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 整数
int value = 123;
// 默认十进制: 123
cout << std::format("{}", value) << endl;
// 十进制: 123
cout << std::format("{:d}", value) << endl;
// 十六进制小写: 7b
cout << std::format("{:x}", value) << endl;
// 十六进制大写: 7B
cout << std::format("{:X}", value) << endl;
// 二进制: 1111011
cout << std::format("{:b}", value) << endl;
// 二进制: 1111011
cout << std::format("{:B}", value) << endl;
// 八进制: 173
cout << std::format("{:o}", value) << endl;
return 0;
}
前缀控制
| 格式 |
说明 |
示例(值 = 42) |
输出 |
#b |
二进制 + 0b 前缀 |
{:b} → {:#b} |
101010 → 0b101010 |
#B |
二进制 + 0B 前缀 |
{:b} → {:#B} |
101010 → 0B101010 |
#o |
八进制 + 0 前缀 |
{:o} → {:#o} |
52 → 052 |
#x |
十六进制 + 0x 前缀 |
{:x} → {:#x} |
2a → 0x2a |
#X |
十六进制 + 0X 前缀 |
{:X} → {:#X} |
2A → 0X2A |
#d |
十进制(# 无效) |
{:d} → {:#d} |
42 → 42 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 整数
int value = 123;
// 十六进制小写带前缀 0x7b
cout << std::format("{:#x}", value) << endl;
// 十六进制大写带前缀 0x7B
cout << std::format("{:#X}", value) << endl;
// 二进制带前缀: 0b1111011
cout << std::format("{:#b}", value) << endl;
// 二进制带前缀: 0B1111011
cout << std::format("{:#B}", value) << endl;
// 八进制带前缀: 0173
cout << std::format("{:#o}", value) << endl;
return 0;
}
符号控制(sign)
| 选项 |
说明 |
正数示例(42) |
负数示例(-42) |
+ |
总是显示符号 |
+42 |
-42 |
- |
仅负数显示符号(默认) |
42 |
-42 |
| 空格 |
正数前加空格,负数正常 |
␣42 |
-42 |
cpp
复制代码
int main()
{
// 总是显示符号
cout << std::format("{:+}", 40) << endl;
// 仅负数显示符号(默认)
cout << std::format("{:-}", 40) << endl;
// 正数前加空格,负数正常
cout << std::format("{: }", 40) << endl;
// 总是显示符号
cout << std::format("{:+}", -40) << endl;
// 仅负数显示符号(默认)
cout << std::format("{:-}", -40) << endl;
// 正数前加空格,负数正常
cout << std::format("{: }", -40) << endl;
return 0;
}
对齐与填充([fill]align + width)
| 对齐方式 |
说明 |
示例(值=42, width=6) |
输出 |
> |
右对齐(默认) |
{:6} |
42 |
< |
左对齐 |
{:<6} |
42 |
^ |
居中对齐 |
{:^6} |
42 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 默认居右对齐 123
cout << std::format("{:>8d}", 123) << endl;
// 指定居右对齐 123
cout << std::format("{:>8d}", 123) << endl;
// 指定居左对齐 123
cout << std::format("{:<8d}", 123) << endl;
// 指定居中对齐 123
cout << std::format("{:^8d}", 123) << endl;
return 0;
}
零填充(0 标志)
| 格式 |
说明 |
示例(值=42, width=6) |
输出 |
06 |
用 0 填充,等价于 {:0>6} |
{:06} |
000042 |
+06 |
带符号零填充 |
{:+06} |
+00042 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 000123
cout << std::format("{:06}", 123) << endl;
// +00123
cout << std::format("{:+06}", 123) << endl;
// -00123
cout << std::format("{:+06}", -123) << endl;
return 0;
}
2、浮点数格式化
std::format("{:格式说明符}", 浮点数值);
- 格式说明符结构 :
[[fill]align][sign]["#"]["0"][width]["." precision][type]
浮点数格式类型(type)
F 仅在值为 inf/nan 时显示为 INF/NAN(大写),否则与 f 相同
g/G 在指数 ≥ -4 且 < precision 时使用 f,否则用 e/E
| 类型 |
名称 |
说明 |
示例(值 = 123.456) |
输出 |
f / F |
定点表示 |
小写/大写(对 inf/nan 有影响) |
{:f} |
123.456000 |
e / E |
科学计数法 |
小写 e / 大写 E |
{:e} |
1.234560e+02 |
g / G |
通用格式 |
自动选择 f 或 e,去除尾随零 |
{:g} |
123.456 |
a / A |
十六进制浮点 |
以十六进制表示(0xh.hhhp±d) |
{:a} |
0x1.edd2f1a9fbe77p+6 |
| (空) |
默认 |
等价于 g |
{} |
123.456 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 浮点数
float value = 123.456;
// 定点表示:f
cout << std::format("{:f}", value) << endl;
// 科学计数法:e
cout << std::format("{:e}", value) << endl;
// 通用格式:g
cout << std::format("{:g}", value) << endl;
// 十六进制浮点:a
cout << std::format("{:a}", value) << endl;
// 默认,等价g
cout << std::format("{}", value) << endl;
return 0;
}
精度(precision)控制
| 格式 |
说明 |
默认精度 |
示例(值 = 123.456789) |
输出 |
.{n} |
指定小数位数或有效数字 |
6 |
:.2f |
123.46 |
| (无) |
使用默认精度 |
6 |
:f |
123.456000 |
各类型对 precision 的解释: |
|
|
|
|
| 类型 |
precision 含义 |
示例(precision=3) |
f / F |
小数点后位数 |
123.457 |
e / E |
小数点后位数 |
1.235e+02 |
g / G |
总有效数字位数 |
123 |
a / A |
十六进制小数位数 |
0x1.eddp+6 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 浮点数
float value = 123.456;
// 定点表示:f,小数点后位数
cout << std::format("{:.2f}", value) << endl;
// 科学计数法:e,小数点后位数
cout << std::format("{:.2e}", value) << endl;
// 通用格式:g,总有效数字位数
cout << std::format("{:.2g}", value) << endl;
// 十六进制浮点:a,十六进制小数位数
cout << std::format("{:.2a}", value) << endl;
// 默认,等价g
cout << std::format("{}", value) << endl;
return 0;
}
前缀与特殊值(# 标志)
| 格式 |
作用 |
示例(值 = 123.0) |
输出 |
# |
强制显示小数点和至少一位小数 |
:#.0f |
123. |
| (无) |
不强制小数点 |
:.0f |
123 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
cout << std::format("{:#.0f}", 123.456) << endl;
cout << std::format("{:.0f}", 123.456) << endl;
cout << std::format("{:#.1f}", 123.456) << endl;
cout << std::format("{:.1f}", 123.456) << endl;
float value = 123;
cout << std::format("{:#.1f}", value) << endl;
cout << std::format("{:.1f}", value) << endl;
return 0;
}
符号控制(sign)
| 选项 |
说明 |
正数示例(123.45) |
负数示例(-123.45) |
+ |
总是显示符号 |
+123.45 |
-123.45 |
- |
仅负数显示符号(默认) |
123.45 |
-123.45 |
| 空格 |
正数前加空格 |
␣123.45 |
-123.45 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 总显示符号
cout << std::format("{:+}", 123.456) << endl;
cout << std::format("{:+}", -123.456) << endl;
// 负数显示符号
cout << std::format("{:-}", 123.456) << endl;
cout << std::format("{:-}", -123.456) << endl;
// 正数前加空格
cout << std::format("{: }", 123.456) << endl;
cout << std::format("{: }", -123.456) << endl;
return 0;
}
对齐、填充与宽度
| 对齐方式 |
说明 |
示例(值=123.45, width=10) |
输出 |
> |
右对齐(默认) |
{:10.2f} |
123.45 |
< |
左对齐 |
:{:<10.2f} |
123.45 |
^ |
居中 |
:{:^10.2f} |
123.45 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 默认居右对齐
cout << std::format("{:>10.2f}", 123.45) << endl;
// 指定居右对齐
cout << std::format("{:>10.2f}", 123.45) << endl;
// 指定居左对齐
cout << std::format("{:<10.2f}", 123.45) << endl;
// 指定居中对齐
cout << std::format("{:^10.2f}", 123.45) << endl;
return 0;
}
零填充(0 标志)
| 格式 |
说明 |
示例(值=123.45, width=10) |
输出 |
010.2f |
用 0 填充,等价于 {:0>10.2f} |
{:010.2f} |
0000123.45 |
+010.2f |
带符号零填充 |
:{:+010.2f} |
+000123.45 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 负数显示符号补0
cout << std::format("{:010.2f}", 123.45) << endl;
cout << std::format("{:010.2f}", -123.45) << endl;
// 强制符号补0
cout << std::format("{:+010.2f}", 123.45) << endl;
cout << std::format("{:+010.2f}", -123.45) << endl;
return 0;
}
特殊浮点值处理
| 值 |
f |
F |
e |
E |
g |
G |
+∞ |
inf |
INF |
inf |
INF |
inf |
INF |
-∞ |
-inf |
-INF |
-inf |
-INF |
-inf |
-INF |
NaN |
nan |
NAN |
nan |
NAN |
nan |
NAN |
字符(串)格式化
常用风格
| 格式说明符 |
描述 |
示例代码 |
输出结果 |
说明 |
{} |
默认格式 |
std::format("{}", "Hello") |
Hello |
直接输出字符串 |
{:s} |
字符串格式 |
std::format("{:s}", "World") |
World |
显式指定字符串格式 |
{:.N} |
截断到N个字符 |
std::format("{:.3}", "Hello") |
Hel |
只显示前3个字符 |
{:.0} |
空字符串 |
std::format("{:.0}", "Hello") |
`` |
截断为0长度 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
std::string value = "hello测试数据world";
// 默认格式
cout << std::format("{}", value) << endl;
// 字符串格式
cout << std::format("{:s}", value) << endl;
// 截断到N个字符
cout << std::format("{:.3}", value) << endl;
cout << std::format("{:.0}", value) << endl;
cout << std::format("{:.3s}", value) << endl;
cout << std::format("{:.0s}", value) << endl;
return 0;
}
对齐和填充
| 格式说明符 |
对齐方式 |
示例代码 |
输出结果 |
说明 |
{:>N} |
右对齐 |
std::format("{:>10}", "Hi") |
Hi |
总宽度10,右对齐 |
{:<N} |
左对齐 |
std::format("{:<10}", "Hi") |
Hi |
总宽度10,左对齐 |
{:^N} |
居中对齐 |
std::format("{:^10}", "Hi") |
Hi |
总宽度10,居中 |
{:*>N} |
自定义填充字符(右对齐) |
std::format("{:*>10}", "Hi") |
********Hi |
用*填充 |
{:*<N} |
自定义填充字符(左对齐) |
std::format("{:*<10}", "Hi") |
Hi******** |
用*填充 |
{:*^N} |
自定义填充字符(居中) |
std::format("{:*^10}", "Hi") |
****Hi**** |
用*填充居中 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
std::string value = "hello测试数据world";
// 居右对齐
cout << std::format("{:>20}", value) << endl;
// 居左对齐
cout << std::format("{:<20}", value) << endl;
// 居中对齐
cout << std::format("{:^20}", value) << endl;
// 居右对齐,左边补*
cout << std::format("{:*>20}", value) << endl;
// 居左对齐,右边补*
cout << std::format("{:*<20}", value) << endl;
// 居中对齐,两边补*
cout << std::format("{:*^20}", value) << endl;
return 0;
}
字符格式化
| 格式说明符 |
描述 |
示例代码 |
输出结果 |
说明 |
{} |
默认字符格式 |
std::format("{}", 'A') |
A |
输出字符本身 |
{:c} |
字符格式 |
std::format("{:c}", 'B') |
B |
显式字符格式 |
{:d} |
十进制数值 |
std::format("{:d}", 'A') |
65 |
ASCII/Unicode值 |
{:x} |
十六进制小写 |
std::format("{:x}", 'A') |
41 |
十六进制ASCII值 |
{:X} |
十六进制大写 |
std::format("{:X}", 'A') |
41 |
大写十六进制 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 默认格式
cout << std::format("{}", 'A') << endl;
// 字符格式
cout << std::format("{:c}", 'A') << endl;
// 十进制格式
cout << std::format("{:d}", 'A') << endl;
// 十六进制小写格式
cout << std::format("{:x}", 'A') << endl;
// 十六进制大写格式
cout << std::format("{:X}", 'A') << endl;
return 0;
}
布尔值格式化
| 格式说明符 |
描述 |
示例代码 |
输出结果 |
C++20 标准支持 |
{} |
默认字符串格式 |
std::format("{}", true) |
"true" |
✅ 完全支持 |
{} |
默认字符串格式 |
std::format("{}", false) |
"false" |
✅ 完全支持 |
{:d} |
十进制整数格式 |
std::format("{:d}", true) |
"1" |
✅ 完全支持 |
{:d} |
十进制整数格式 |
std::format("{:d}", false) |
"0" |
✅ 完全支持 |
{:b} |
二进制格式 |
std::format("{:b}", true) |
"1" |
✅ 完全支持 |
{:b} |
二进制格式 |
std::format("{:b}", false) |
"0" |
✅ 完全支持 |
{:x} |
十六进制小写 |
std::format("{:x}", true) |
"1" |
✅ 完全支持 |
{:X} |
十六进制大写 |
std::format("{:X}", true) |
"1" |
✅ 完全支持 |
{:o} |
八进制格式 |
std::format("{:o}", true) |
"1" |
✅ 完全支持 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 默认字符串格式 true|false
cout << std::format("{}", true) << endl;
cout << std::format("{}", false) << endl;
// 十进制整数格式 1|0
cout << std::format("{:d}", true) << endl;
cout << std::format("{:d}", false) << endl;
return 0;
}
对齐填充
| 格式说明符 |
描述 |
示例代码 |
输出结果 |
应用场景 |
{:>5} |
右对齐,宽度5 |
std::format("{:>5}", true) |
" true" |
表格对齐 |
{:<6} |
左对齐,宽度6 |
std::format("{:<6}", false) |
"false " |
列表显示 |
{:^8} |
居中对齐,宽度8 |
std::format("{:^8}", true) |
" true " |
标题居中 |
{:*>5} |
右对齐,星号填充 |
std::format("{:*>5}", false) |
"*false" |
装饰性输出 |
{:0>3d} |
数值右对齐,零填充 |
std::format("{:0>3d}", true) |
"001" |
固定宽度数字 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 居右对齐,左边补*
cout << std::format("{:>10}", true) << endl;
cout << std::format("{:>10}", false) << endl;
// 居左对齐,右边补*
cout << std::format("{:<10}", true) << endl;
cout << std::format("{:<10}", false) << endl;
// 居中对齐,两边补*
cout << std::format("{:^10}", true) << endl;
cout << std::format("{:^10}", false) << endl;
// 居右对齐,左边补*
cout << std::format("{:*>10}", true) << endl;
cout << std::format("{:*>10}", false) << endl;
// 居左对齐,右边补*
cout << std::format("{:*<10}", true) << endl;
cout << std::format("{:*<10}", false) << endl;
// 居中对齐,两边补*
cout << std::format("{:*^10}", true) << endl;
cout << std::format("{:*^10}", false) << endl;
return 0;
}
日期格式化
日期格式说明
| 说明符 |
含义 |
示例输出 |
说明 |
%Y |
四位年份 |
2026 |
完整的公历年份 |
%y |
两位年份 |
26 |
年份的后两位 |
%C |
世纪 |
20 |
年份除以100的整数部分 |
%G |
ISO 8601 基于周的年份(4位) |
2026 |
可能与 %Y 不同(跨年周) |
%g |
ISO 8601 基于周的年份(2位) |
26 |
%G 的后两位 |
%m |
月份(补零) |
02 |
01--12 |
%b / %h |
月份缩写名 |
Feb |
本地化缩写 |
%B |
月份全名 |
February |
本地化全名 |
%d |
日(补零) |
05 |
01--31 |
%e |
日(补空格) |
5 |
1--31,个位数前补空格 |
%j |
一年中的第几天 |
042 |
001--366 |
%D |
等价于 %m/%d/%y |
02/11/26 |
美式日期短格式 |
%F |
等价于 %Y-%m-%d |
2026-02-11 |
ISO 8601 日期格式 |
%x |
本地化日期表示 |
02/11/26 |
取决于 locale |
时间格式说明
| 说明符 |
含义 |
示例输出 |
说明 |
%H |
24小时制小时(补零) |
16 |
00--23 |
%I |
12小时制小时(补零) |
04 |
01--12 |
%M |
分钟(补零) |
33 |
00--59 |
%S |
秒(补零) |
05 |
00--60(含闰秒) |
%p |
AM/PM |
PM |
本地化的上午/下午标识 |
%R |
等价于 %H:%M |
16:33 |
24小时制时分 |
%T |
等价于 %H:%M:%S |
16:33:05 |
24小时制时分秒 |
%r |
12小时制时间 |
04:33:05 PM |
本地化的12小时制表示 |
%X |
本地化时间表示 |
16:33:05 |
取决于 locale |
星期格式说明
| 说明符 |
含义 |
示例输出 |
说明 |
%a |
星期缩写名 |
Wed |
本地化缩写 |
%A |
星期全名 |
Wednesday |
本地化全名 |
%u |
ISO 星期几(数字) |
3 |
1(周一)--7(周日) |
%w |
星期几(数字) |
3 |
0(周日)--6(周六) |
%U |
一年中的第几周(周日起始) |
06 |
00--53 |
%W |
一年中的第几周(周一起始) |
06 |
00--53 |
%V |
ISO 8601 周数 |
07 |
01--53 |
时区格式说明
| 说明符 |
含义 |
示例输出 |
说明 |
%Z |
时区缩写 |
CST |
时区名称缩写 |
%z |
UTC 偏移 |
+0800 |
格式为 ±hhmm |
%Ez / %Oz |
UTC 偏移(带冒号) |
+08:00 |
修改后的格式 |
%c |
本地化日期时间表示 |
Wed Feb 11 16:33:05 2026 |
完整的本地化日期时间 |
%n |
换行符 |
\n |
输出换行 |
%t |
水平制表符 |
\t |
输出制表符 |
%% |
字面量 % |
% |
输出百分号本身 |
亚秒精度
| 说明符 |
含义 |
示例输出 |
说明 |
%S |
秒(自动含小数部分) |
05.123456 |
当 duration 精度高于秒时,自动输出小数部分 |
%Q |
tick 计数 |
1234567890 |
duration 的 count() 值 |
%q |
单位后缀 |
ms |
duration 的单位缩写 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
// 2026-01-01
cout << std::format("{:%Y-%m-%d}", std::chrono::system_clock::now()) << endl;
// 26-01-01
cout << std::format("{:%y-%m-%d}", std::chrono::system_clock::now()) << endl;
// 2026-01-01 01:01:01.222
cout << std::format("{:%Y-%m-%d %H:%M:%S}", std::chrono::system_clock::now()) << endl;
// 精度到秒
auto now = std::chrono::floor<std::chrono::seconds>(std::chrono::system_clock::now());
cout << std::format("{:%Y-%m-%d %H:%M:%S}", now) << endl;
cout << std::format("{:%F %T}", now) << endl;
return 0;
}
参数索引
基本用法
| 语法形式 |
描述 |
示例代码 |
输出结果 |
说明 |
{} |
自动索引(按顺序) |
std::format("{}", "Hello") |
"Hello" |
从参数0开始自动递增 |
{0} |
显式索引0 |
std::format("{0}", "Hello") |
"Hello" |
明确指定第一个参数 |
{1} |
显式索引1 |
std::format("{1} {0}", "World", "Hello") |
"Hello World" |
可以重新排列参数顺序 |
{2} |
显式索引2 |
std::format("{2} {1} {0}", "!", "World", "Hello") |
"Hello World !" |
支持任意顺序 |
混合使用
| 混合模式 |
是否允许 |
示例代码 |
结果 |
C++20 标准规定 |
| 全自动索引 |
✅ 允许 |
std::format("{} {} {}", "A", "B", "C") |
"A B C" |
所有占位符都无索引 |
| 全显式索引 |
✅ 允许 |
std::format("{0} {1} {2}", "A", "B", "C") |
"A B C" |
所有占位符都有索引 |
| 混合索引 |
❌ 禁止 |
std::format("{} {1}", "A", "B") |
编译错误 |
C++20 严格禁止混合使用 |
| 混合索引 |
❌ 禁止 |
std::format("{0} {}", "A", "B") |
编译错误 |
同上 |
cpp
复制代码
int main()
{
std::cout << "__cplusplus = " << __cplusplus << endl;
auto a = "hello", b = "张三", c = "world";
cout << std::format("{}{}{}", a, b, c) << endl;
cout << std::format("{2}{1}{0}", c, b, a) << endl;
// 不允许混合使用
// cout << std::format("{}{1}{2}", a, b, c) << endl;
// 指定长度对齐
cout << std::format("{0:<10}{1:<10}{2:<10}", a, b, c) << endl;
return 0;
}