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 | 指定输出类型,
bB表示以二进制输出;
xX表示以十六进制输出;
o表示以八进制输出;
eE表示使用科学计数法;
fF表示以固定精度输出;
gG表示以指数的通用表示法输出;
aA表示以十六进制表示法输出。

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位。

作者:cwtxx

出处:https://www.cnblogs.com/cwtxx/p/18718162

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   cwtxx  阅读(21)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示