C++20中的字符串格式化方式format
使用format格式化字符串#
在初学C时大多数人写下的第一行代码应该都是hello world
吧,其中使用到了打印函数printf
,可以像这样使用:
int main() {
const char* str = "hello, world";
printf("%s", str);
}
这是很常用的输出方式,但是奇怪的是C++一直没有支持这种格式化字符串的方式(可能是因为C++完全兼容C?不过用C风格写C++总是感觉有点不爽),虽然流式的输出方式大多情况下也挺好用,但是在需要大量格式化参数的情况下简直是折磨老太太的裹脚布——又臭又长。
好在C++20引入了format
来支持字符串的格式化。
format的使用方式#
可以像C中的格式化方式一样使用format
,比如
string str{format("c++20 format int {}, char {}", 42, 'c')};
cout << str << endl;
输出结果
c++20 format int 42, char c
format
通过{}
来表示占位符,并且可以自动推导参数的类型。还可以通过输出迭代器的形式格式化字符串到一个string中
string str2;
format_to(back_inserter(str2), "init int[{}], float[{}]", 42, 3.14);
cout << str2 << endl;
输出
init int[42], float[3.14]
还支持手动指定下标,不过手动指定和自动指定不能混合使用
string str3 = format("fist =[{1}], second = [{0}]", 1, 0);
cout << str3 << endl;
输出
fist =[0], second = [1]
需要注意的是,以上的使用都是针对的编译期常量字符串,也就是说要格式化的字符串需要是能在编译期就确定是什么样的,否则编译器会报错。如果字符串不能在编译期确定,那么需要使用以下形式:
string tmp_fmt{ "hello, {1}! there is number {0}" };
string name{ "xiaoming" };
int num = 42;
string str4 = vformat(tmp_fmt, make_format_args(42, name));
cout << str4 << endl;
输出结果
hello, xiaoming! there is number 42
这里允许tmp_fmt
是个在运行期才确定的字符串,然后通过使用make_format_args
这个函数给字符串指定参数,格式化后再输出。
格式控制#
直接给出format
的格式控制方式.
{[placeholder]:[[fill]align][sign][#][0][width][.precision][type]}
以:
来表示启动格式化方式,方括号中的各部分都是可选的。
参数 | 说明 |
---|---|
placeholder: 前面说过了,表示从0开始数传递的第几个格式化的内容,可以省略。 | |
[fill]align | [fill]指定占位符的填充格式字符, align表示fill填充的字符的对齐方式, < 表示左对齐,^ 表示居中对齐,> 表示右对齐。 |
sign | 是数值符号显示标识,+ 表示显示正负号;- 表示只显示负号(默认格式);空格表示正数显示空格,负数显示负号。 |
| 表示显示前缀0b、0x等,浮点数显示小数点。#
0 | 表示补零,如果指定了对齐方式会被忽略。
width| 指定了字段的最小宽度。
.precision | 指定浮点数小数位数,和字符串输出字符数。
type | 指定输出类型,b
或B
表示以二进制输出;x
或X
表示以十六进制输出;o
表示以八进制输出;e
或E
表示使用科学计数法;f
或F
表示以固定精度输出;g
或G
表示以指数的通用表示法输出;a
或A
表示以十六进制表示法输出。
str = format("fill_, align 左对齐, width = 9, string = |{:_<9}|", 42);
cout << str << endl;
str = format("fill~, align 居中, width = 9, string = |{:~^9}|", 42);
cout << str << endl;
str = format("fill+, align 右对齐, width = 9, string = |{:+>9}|", 42);
cout << str << endl;
double pi = 3.14159265354;
cout << format("int type, sign +, type x, with 0 |{:+010x}|", 42) << endl;
cout << format("int type, sign +, type X, with # |{:+#10X}|", 42) << endl;
cout << format("double type, type e, precision = 3, |{:^#10.3e}|", pi) << endl;
输出结果
fill_, align 左对齐, width = 9, string = |42_______|
fill~, align 居中, width = 9, string = |~~~42~~~~|
fill+, align 右对齐, width = 9, string = |+++++++42|
int type, sign +, type x, with 0 |+00000002a|
int type, sign +, type X, with # | +0X2A|
double type, type e, precision = 3, |3.142e+00 |
动态指定格式#
格式控制也是可以动态指定参数的
cout << format("[{0:<{2}.{1}}]", 3.14159265354, 10, 20) << endl; // [3.141592654 ]
cout << format("[{0:<{2}.{1}f}]", 3.14159265354, 10, 20) << endl; // [3.1415926535 ]
这里格式控制的参数也是通过外部的参数传递进来的,最终的结果是输出一个表示圆周率的小数,整个字符串占20字节。另外,默认情况下浮点数的精度控制是指输出的有效数字个数,如果是指定固定精度情况下,.mf
固定输出小数点后m位。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探