现代 C++ 编程实战
吴咏炜
前 Intel 资深软件架构师
35859 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 57 讲
现代 C++ 编程实战
15
15
1.0x
00:00/00:00
登录|注册

45 | format和print:全新的格式化输出方案

你好,我是吴咏炜。今天,我们一起来聊聊全新的格式化输出方案:formatprint

背景:C++20 之前各种输出方案的问题

C++ 从很早开始,就引入了 IO stream 来解决 printf 系列函数固有的种种问题。这个方案总体上是成功的,因为 printf 本身确实缺点多多:
原则上类型不安全。当你格式化字符串里写了某种类型,而实际提供了另一种类型时(如 printf("%s\n", 42)),编译器不一定能发现这个问题。某些编译器在当你以常量形式给出格式化字符串时(最常见情况),能检查实际参数类型跟格式化字符串里指定的类型是否匹配,但当你自己的函数需要接受格式化字符串,编译器就没法帮你检查了——除非你使用编译器提供的某些特殊扩展方式。
不直接支持固定宽度的整数类型。可以用 %d 表示 int,用 %lu 表示 unsigned long,但你应当用什么来格式化 uint32_t 呢?标准的解决方式是使用 PRIu32(你知道吗?):如果要把 "Value: %d\n" 里的整数类型改成 uint32_t,那正确的格式化字符串写法是 "Value: %" PRIu32 "\n"
不支持自定义扩展。如果想用格式化字符串输出你自己的自定义类,那,哼哼,没门(所以,要输出时间只能另加了个 strftime 函数)。
字符串输出使用定长缓冲区。如果你的输出不是直接到文件,而是到字符串,那输出的缓冲区大小需要在调用函数前确定。sprintf 具有缓冲区溢出问题,snprintf 及其他“更安全”的版本也要求你提前确定缓冲区大小。
……
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
  • 解释
  • 总结

1. C++20引入了全新的格式化输出方案`format`和`print`,解决了之前输出方案的问题,提高了代码简单性和执行性能。 2. `format`是最基本的格式化工具,根据给定的格式化字符串将其他参数格式化成字符串,使用`{}`表示格式占位符,支持不同类型的格式说明,要求格式化字符串是编译期常量,并在编译时检查格式化字符串和参数是否匹配。 3. `print`是`format`的衍生功能,提供了更方便的格式化输出方式,使用C++23的话,可以直接使用`print("{:02X}", c)`来格式化输出。 4. fmt库可以看作是`std::format`的参考实现,对于较老的C++版本,无法使用标准库里的`format`和`print`,可以通过fmt库实现相应功能,但一般推荐使用标准库提供的功能。 5. 标准库对象的 `format` 支持在C++20中得到了格式化支持,包括chrono库里的对象,如日期和系统时钟时间点。 6. 自定义对象的 `format` 支持可以通过提供特化版本来实现,需要在`std`命名空间里写出对自定义对象类型的特化。 7. 使用编译期确定的格式化字符串比较安全和高效,如果格式化字符串在编译期无法确定,需要使用`vformat`。 8. C++23进一步添加了对更多标准库对象类型的格式化支持,包括范围、容器适配器、`pair`、`tuple`等对象都能直接输出。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《现代 C++ 编程实战》
新⼈⾸单¥59
立即购买
登录 后留言

精选留言

由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。
收起评论
显示
设置
留言
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部
文章页面操作
MAC
windows
作用
esc
esc
退出沉浸式阅读
shift + f
f11
进入/退出沉浸式
command + ⬆️
home
滚动到页面顶部
command + ⬇️
end
滚动到页面底部
⬅️ (仅针对订阅)
⬅️ (仅针对订阅)
上一篇
➡️ (仅针对订阅)
➡️ (仅针对订阅)
下一篇
command + j
page up
向下滚动一屏
command + k
page down
向上滚动一屏
p
p
音频播放/暂停
j
j
向下滚动一点
k
k
向上滚动一点
空格
空格
向下滚动一屏
播放器操作
MAC
windows
作用
esc
esc
退出全屏
⬅️
⬅️
快退
➡️
➡️
快进
空格
空格
视频播放/暂停(视频全屏时生效)