虽然 C++20 已经提供了 std::format 这种格式化库,但直到 C++23 才支持 std::print 这种便利库。
又由于目前 gcc 对 C++23 支持还不完整,尤其是在嵌入式上。所以仍然是需要以 fmt 库 为基本使用工具。
包含 fmt 库
Get Started中已经详细的描述了如何包含 fmt 到项目中去,为了增加项目的独立性,个人更倾向于使用FetchContent或Embedded的方式包含该库。
除了上面说的方法,还有一个简单粗暴的办法:
下载源码,将文件夹
inculde/fmt和src拷贝至项目中将
fmt/core.h,fmt/format.h,fmt/forat-inl.h,src/format.cc添加至编译文件中将
fmt路径添加到项目包含路径中
1 | 对于 Visual Studio,为了能够顺利编译 fmt 库。 |
基本语法
fmt::format和fmt::print语法一致,在字符串中使用花括号{}表示格式化输出部分,如果想输出花括号,则使用两个花括号{{}}。
替换字段{}的语法如下:
1 | replacement_field ::= "{" [arg_id] [":" (format_spec | chrono_format_spec)] "}" |
arg_id
arg_id指的是要输出部分对应后面输入参数的顺序,默认为0~9这样的顺序:
1 | fmt::println("{}{}{}\n", "0", "1", "2"); |
如果在arg_id后需要增加其他描述,那需要以冒号:分隔arg_id和format_spec。
format_spec
format_spec描述参数的表示方式,包含长度、对其、空白填充、精度、进制等。
1 | format_spec ::= [[fill]align][sign]["#"]["0"][width]["." precision]["L"][type] |
fill表示填充的字符,除了花括号以外,其他字符都可以使用(需要指定宽度才有意义)align指定对齐方式(需要指定宽度才有意义):<:左对齐,默认值>:右对齐,对于数值而言,它是默认值^:居中对齐
1 | fmt::format("{:<30}", "left aligned"); |
sign仅在浮点数或有符号整数有效:+:在数值为非负时加上+号,在数值为负数时加上-号-:只有在数字为负数时,才加上-号,它是默认值:在数值为非负数时,加上空格,在数值为负数时加上-号
#用于对显示格式的切换,仅对整数和浮点数合法:- 对于
#b or #B二进制、#o8进制、#x or #X16进制,会输出对应的前缀
- 对于
width指定显示的最小位数,如果在width前面加0,则会在符号和数值之间填充0.- 当使用对齐方式时,前面加
0的方式就会被忽略
- 当使用对齐方式时,前面加
precision指定小数精度:对于
f or F显示格式,指定小数点后面的位数对于
g or G显示格式,指定除小数点外的位数之和
type用于指定具体显示格式:对于字符串有:
s:字符串显示,默认值?:调试显示,字符串被引号包含,且里面的特殊字符将不会被转义
对于字符有:
c:字符显示,默认值?:调试显示,字符被引号包含,且特殊字符不会被转义
对于整数有:
b或B:以二进制显示,如果加上#则会分别加上0b和0B前缀c:以字符显示d:以十进制显示o:以八进制显示x或X:以 16 进制显示,如果加上#则会分别加上0x和0X前缀
对于浮点数有:
a或A:以 16 进制显示浮点数e或E:以科学计数法表示浮点数f或F:以固定精度显示浮点数g或G:对浮点数进行四舍五入
对于指针有:
fmt::print("{:p}", fmt::ptr(p));p:以 16 进制的方式显示指针,默认值。
1 | fmt::format("{:.{}f}", 3.14, 1); |