C++ 好用的格式化库--fmt
背景
fmt 库是一个开源的 C++ 格式化库,它提供了一种简洁、安全和高效的方式来进行字符串格式化。
该库的设计目标是提供与 Python 的字符串格式化语法类似的功能,同时保持 C++ 的类型安全性和性能。
下载与安装
官网下载
fmt 官网地址:https://fmt.dev/latest/index.html。
可以从官网或者 GitHub 存储库 (https://github.com/fmtlib/fmt) 下载源代码并手动构建。
使用 vcpkg 安装
fmt 也可以通过 vcpkg 包管工具进行下载安装:

header-only
fmt 库也支持 header-only 方式使用,需要设置 FMT_HEADER_ONLY 宏。
#define FMT_HEADER_ONLY
#include "fmt/core.h"
hello world
下面是一个使用C++fmt库的简单示例:
#include "fmt/core.h"int main()
{fmt::print("hello {}", "world");return 0;
}
运行上述代码,将输出以下结果:

基本格式化语法
参数替换
类似于 printf 的 % 占位符输出,fmt 使用大括号替代参数,且和参数类型无关:
#include "fmt/core.h"int main()
{fmt::print("hello {}", 123);return 0;
}
运行上述代码,将输出以下结果:

按位置替换参数
参数位置默认从 0 开始:
#include "fmt/core.h"int main()
{fmt::print("{0}+{1}={2}", 1,2,3);return 0;
}
运行上述代码,将输出以下结果:

如果没有指定位置,默认从 0 往后依次替换:
fmt::print("{}+{}={}", 1,2,3);
运行上述代码,将输出以下结果:

参数格式化
可以要按指定格式替换指定位置的参数,用 {位置:格式} 的形式表示替换内容。
指定填充字符
可以指定字符串长度,若长度不够则使用指定的字符进行填充。
右侧填充
使用 < 表示右填充,即文本居左:
fmt::print("{0:*<10}", "hello");
运行结果如下:

左侧填充
使用 > 表示左填充,即文本居右:
fmt::print("{0:*>10}", "hello");
运行结果如下:

两边填充
使用 ^ 表示在两层填充,即文本居中:
fmt::print("{0:*^10}", "hello");
运行结果如下:

默认填充字符
可以指定填充字符时,默认使用空格进行填充:
fmt::print("{0:>10}\n{1:>10}", "hello","world");
运行结果如下:

动态设置字符串长度
字符串的长度也可以用参数指定:
fmt::print("{0:>{1}}\n{2:>10}", "hello",20,"world");
运行结果如下:

按精度格式化
使用 . 表示精度格式化。
格式化字符串长度
使用 .n 表示把字符串的长度格式为 n :
fmt::print("{0:.4}", "abcdefg");
运行结果如下:

格式化浮点数长度
使用 .n 也可以用来表示把浮点数长度为 n :
fmt::print("{0:.3}", 1.23456);
运行结果如下:

格式化小数位数
使用 .nf 表示把浮点数小数位数格式化为 n:

动态设置精度
精度值也可以通过参数动态设置:
fmt::print("{0:.{1}f}", 3.141596,2);
运行结果如下:

数字正负号格式化
用于格式化数字正负符号显示。
仅负数显示符号
使用 - 表示仅负数显示符号:
fmt::print("正数:{0:}\n负数:{1:}", 30,-20);
运行结果如下:

正负数都显示符号:
使用 + 表示正负数字都显示符号:
fmt::print("正数:{0:+}\n负数:{1:+}", 30,-20);
运行结果如下:

数字进制格式化
格式化为10进制
使用 d 表示格式化数字为10进制进行显示:
fmt::print("10进制:{0:d}", 10);
运行结果如下:

格式化为2进制
使用 b 表示格式化数字为2进制进行显示:
fmt::print("2进制:{0:b}", 10);
运行结果如下:

格式化为16进制
使用 x 表示格式化数字为16进制进行显示:
fmt::print("16进制:{0:x}", 10);
运行结果如下:

显示进制符号
在进制符号前加 # 可以在进制格式化时增加符号标记:
fmt::print("16进制:{0:#x}", 10);
运行结果如下:

格式化数字长度
在进制符号前可以增加长度表示,长度不够补 0 :
fmt::print("{0:08d}", 10);
运行结果如下:

fmt 库使用
格式化内容到字符串
fmt::format 方法会把格式化的结果转为字符串:
#include <iostream>
#include "fmt/core.h"int main()
{auto res = fmt::format("hello {}", "world");std::cout << res << std::endl;return 0;
}
运行结果如下:

格式化内容到迭代器
fmt::format_to 方法可以把内容格式化到指定的迭代器:
#include "fmt/core.h"int main()
{std::string s;fmt::format_to(std::back_inserter(s), "hello {}", "world");std::cout << s << std::endl;return 0;
}
运行结果如下:

格式化内容到控制台
fmt::print 方法把格式化结果输出到控制台显示:
fmt::print("hello {}", "world");
fmt 库使用进阶
使用参数格式化
命名参数
使用 fmt::arg 可以构建一个命名参数:
fmt::print("{a:*<10}{b:#x}", fmt::arg("a", "hello"), fmt::arg("b", 100));
运行结果如下:

参数列表
fmt::vformat 支持使用参数列表进行格式化:
#include <iostream>
#include "fmt/core.h"int main()
{const fmt::format_args args = fmt::make_format_args(fmt::arg("a", "hello"),fmt::arg("b", 100));const auto s = fmt::vformat("{a:*<10}{b:#x}", args);std::cout << s << std::endl;return 0;
}
运行结果如下:

同样 fmt::vprint 也支持传入参数列表进行格式化。
自定义类型格式化
特例化 formatter< T > 方式
特例化 fmt::formatter< T > 并且实现其 parse 和 format 方法,可以实现对自定义类型的格式化。
自定义数据类型
使用以下自定义类型作为示例:
struct my_struct
{int id;std::string name;
};
特例化 fmt::formatter< T >
特例化 fmt::formatter< T > 并实现其 parse 和 format 方法:
template <>
struct fmt::formatter<my_struct>
{char presentation = 'f';auto parse(fmt::format_parse_context &ctx) -> decltype(ctx.begin()){auto it = ctx.begin(), end = ctx.end();if (it != end && (*it == 'f' || *it == 'i')) presentation = *it++;if (it != end && *it != '}') throw "invalid format";return it;}template <typename FormatContext>auto format(const my_struct & ms, FormatContext &ctx) const -> decltype(ctx.out()){return presentation == 'f'? fmt::format_to(ctx.out(), "[my_struct]id={},name= {}", ms.id, ms.name): fmt::format_to(ctx.out(), "[my_struct]id={}", ms.id);}
};
使用示例
int main()
{my_struct ms{ 0,"hello" };fmt::print("my_struct f 格式化:{0:f}\nmy_struct i 格式化:{0:i}", ms);return 0;
}
运行结果如下:

继承现有 formatter 类
也可以通过继承现有的 formatter 实现自定义类的格式化:
#include "fmt/core.h"
#include "fmt/format.h"struct my_struct
{int id;std::string name;
};
template <>
struct fmt::formatter<my_struct> : formatter<string_view>
{auto format(my_struct ms, format_context &ctx) const{const auto fmt_str = fmt::format("[my_struct]id={}", ms.id);const fmt::string_view sv(fmt_str.data(),fmt_str.size());return formatter<string_view>::format(sv, ctx);}
};
int main()
{my_struct ms{ 0,"hello" };fmt::print("{}", ms);return 0;
}
运行结果如下:

枚举类型格式化
对于枚举类型 fmt 提供了 format_as 接口用于类型转换。
转底层数据类型
使用 fmt::underlying 可以把枚举值转为底层数据类型:
#include "fmt/core.h"
#include "fmt/format.h"enum class my_enum
{red = 0,green,blue
};
auto format_as(my_enum e)
{return fmt::underlying(e);
}
int main()
{fmt::print("{}", my_enum::green);return 0;
}
运行结果如下:

转其他类型
也可以在 format_as 把枚举值转为其他类型:
#include "fmt/core.h"
#include "fmt/format.h"enum class my_enum
{red = 0,green,blue
};
auto format_as(my_enum e)
{switch (e){case my_enum::red:return "red";case my_enum::green:return "green";case my_enum::blue:return "blue";}
}
int main()
{fmt::print("{}", my_enum::green);return 0;
}
运行结果如下:

容器元素格式化
fmt::join 可以定义分隔符对容器中的元素进行格式化:
int main()
{std::string s = "1234567";fmt::print("{}", fmt::join(s, ", "));return 0;
}
运行结果如下:

对于 std::tuple 可以直接进行格式化操作:
#include "fmt/core.h"
#include <fmt/ranges.h>
int main()
{std::tuple<int, char> t = { 1, 'a' };fmt::print("{}", t);return 0;
}
运行结果如下:

微信搜索“编程猿来如此”关注公众号获取更多内容。
相关文章:
C++ 好用的格式化库--fmt
背景 fmt 库是一个开源的 C 格式化库,它提供了一种简洁、安全和高效的方式来进行字符串格式化。该库的设计目标是提供与 Python 的字符串格式化语法类似的功能,同时保持 C 的类型安全性和性能。 下载与安装 官网下载 fmt 官网地址:https:…...
微信小程序教学系列(3)
微信小程序教学系列 第三章:小程序高级开发技巧 1. 小程序API的使用 小程序API简介 小程序API是小程序提供的一系列接口,用于实现各种功能和操作。通过调用小程序API,可以实现页面跳转、数据存储、网络请求等功能。 使用小程序API的步骤…...
ORB-SLAM系列算法演进
ORB-SLAM算法是特征点法的代表,当前最新发展的ORB-SLAM3已经将相机模型抽象化,适用范围非常广,虽然ORB-SLAM在算法上的创新并不是很丰富,但是它在工程上的创新确实让人耳目一新,也能更好的为AR、机器人的算法实现落地。…...
solidity0.8.0的应用案例11:透明代理合约
选择器冲突 智能合约中,函数选择器(selector)是函数签名的哈希的前4个字节。例如mint(address account)的选择器为bytes4(keccak256("mint(address)")),也就是0x6a627842. 由于函数选择器仅有4个字节,范围很小,因此两个不同的函数可能会有相同的选择器,例如…...
最新消息:谷歌将在Chromebook上运用UWB技术,无线通信更上一层
超宽带(UWB)技术是一种创新的短距离无线通信技术,具有高速数据传输和精确定位物体位置的优势。尽管该技术已经存在一段时间,但最近开始广泛应用于各种设备中。据最新报道,Pixel Watch 2可能会搭载UWB模块,这…...
php+echarts实现数据可视化实例3
效果 全部代码 <?php include(includes/session.inc); include(includes/SQL_CommonFunctions.inc); ?> <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" …...
ubuntu下安装Sphinx,编译pdf
安装WSL2: 以管理员身份打开PowerShellwsl --install 来安装其他 Linux 发行版wsl --list --verbose 查看安装在 Windows 计算机上的 Linux 发行版列表 安装sphinx: sudo apt-get updatesudo apt-get install python3-sphinxsudo apt-get install lat…...
vue2.x项目从0到1(七)之用户权限
此章节偏理论知识 对于小一点的项目 比如说角色都是平级的 那我们直接像之前 vue2.x项目从0到1(二)之后台管理侧边栏(动态渲染路由以及高亮)_vue动态渲染侧边栏_关忆北_的博客-CSDN博客这样渲染就行了 但是一旦项目大了 …...
上传镜像到阿里云的ACR
1、开通阿里云ACR 2、在ACR 中创建命名空间 3、本地安装docker 4、登录到 开通ACR,需要配置访问凭证 [rootmaster ~]# docker login --username***lb registry.cn-beijing.aliyuncs.com Password: 5、给镜像打标签 [rootmaster ~]# docker images REPOSITORY …...
ahooks.js:一款强大的React Hooks库及其API使用教程(五)
一、ahooks.js简介二、ahooks.js安装三、继续ahooks.js API的介绍与使用教程61. useEventTarget62. useExternal63. useFavicon64. useMutationObserver65. useLongPress66. useScroll67. useResponsive68. useFocusWithin69. useControllableValue70. useEventEmitter 一、aho…...
MySQL TCL 事务控制
文章目录 1.事务四大特性2.事务并发问题3.事务隔离级别4.隔离级别查看与设置5.动提交事务5.1 查看自动提交事务5.2 关闭或开启自动提交事务 6.事务执行的基本流程7.设置事务的保存点参考文献 说到事务控制,先说一下数据库的事务是什么以及 MySQL 中我们必知的知识点…...
【Ubuntu】从Graylog到Grafana Loki:构建更强大的网络设备管理和监控系统
在将Graylog部署到生产环境时,我们遇到了一些问题,其中最主要的是无法安装MongoDB并且无法随时重启机器去修改BIOS设置来修复问题 【WARNING: MongoDB 5.0 requires a CPU with AVX support, and your current system does not appear to have that! 】。…...
[JavaWeb]【八】web后端开发-Mybatis
目录 一 介绍 二 Mybatis的入门 2.1 快速入门 2.1.1 准备SpringBoot工程 2.1.2 创建数据库mybatis以及对应库表user 2.1.3 创建User实体类 2.1.4 配置application.properties数据库连接信息 2.1.5 编写sql语句(注解方式) 2.1.6 测试运行 2.1.7 配…...
Flink源码之Checkpoint执行流程
Checkpoint完整流程如上图所示: JobMaster的CheckpointCoordinator向所有SourceTask发送RPC触发一次CheckPointSourceTask向下游广播CheckpointBarrierSouceTask完成状态快照后向JobMaster发送快照结果非SouceTask在Barrier对齐后完成状态快照向JobMaster发送快照结…...
【工具使用】Git的使用
dev代表开发版 1. git clone 命令 通过 git add <name> 对文件进行跟踪,把<name>加入到暂存区 git commit -m XXXXXXX 提交修改并补充XXXXX作为注释 “暂存”状态:出现了一些修改,但是还没有提交 对于Java来说,.cl…...
无涯教程-PHP Installation on Windows NT/2000/XP with IIS函数
在Windows Server上运行IIS的PHP的安装比在Unix上简单得多,因为它涉及的是预编译的二进制文件而不是源代码。 如果您打算在Windows上安装PHP,那么这是先决条件列表- 运行中的PHP支持的Web服务器。一个正确安装的PHP支持的数据库,如MySQL或Oracle等。(如果您打算使用的话) PHP…...
EureKa快速入门
EureKa快速入门 远程调用的问题 多个服务有多个端口,这样的话服务有多个,硬编码不太适合 eureKa的作用 将service的所有服务的端口全部记录下来 想要的话 直接从注册中心查询对于所有服务 每隔一段时间需要想eureKa发送请求 保证服务还存活 动手实践 …...
Sectigo EV代码签名申请步骤
一、EV代码签名申请前提 1、单位成立时间不低于:3个月 2、单位工商及企查查可查 3、单位经营正常 4、注册地址真实存在,禁止使用集中注册地址 5、企查查登记电话和邮箱,确定查询结果的电话可以接听、邮箱可以接收邮件,如果信…...
生信学院|08月25日《SOLIDWORKS PDM帮助企业对设计数据版本的管理应用》
课程主题:SOLIDWORKS PDM帮助企业对设计数据版本的管理应用 课程时间:2023年08月25日 14:00-14:30 主讲人:车立洋 生信科技 PDM专家 1、图纸&文档的版本管理对于企业的重要性 2、SolidWorks PDM对图纸&文档版本的管理 3、SolidW…...
vue页面转pdf后分页时文字被横向割裂
效果 预期效果 //避免分页被截断async outPutPdfFn (id, title) {const _t this;const A4_WIDTH 592.28;const A4_HEIGHT 841.89;// dom的id。let target document.getElementById(pdf);let pageHeight target.scrollWidth / A4_WIDTH * A4_HEIGHT;// 获取分割dom…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)
一、OpenBCI_GUI 项目概述 (一)项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台,其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言,首次接触 OpenBCI 设备时,往…...
