c++ {fmt}库使用指南一

这篇具有很好参考价值的文章主要介绍了c++ {fmt}库使用指南一。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、缘起

夜已深,时针悄悄来到了十一点半,但我的思绪却像一股涌泉般汹涌澎湃,完全无法入眠。此时,我渴望做一些有意义的事情,决定借助这份宁静,沉下心来,撰写一份关于fmt库的使用指南。
fmt库是一个高效、易用的C++格式化库,可以帮助我们方便地进行字符串格式化、输出、日志记录等操作。在这份指南中,我将介绍fmt库的基本用法、格式化字符串语法、异常处理机制等方面的内容,希望能为大家提供帮助。让我们一起开始吧!

二、基本使用

安装fmt库

github: https://github.com/fmtlib/fmt
api指南:https://fmt.dev/latest/api.html

项目中引入fmt库
  1. 老方法 cmake (不推荐)
    mkdir build
    cd build
    cmake …
    make 或者使用ide打开生成的项目文件生成相应的库静态库\
  2. 仅仅包含头文件,(需要在包含头文件之前#define FMT_HEADER_ONLY 推荐)
    • fmt/core.h:char/UTF-8主要的格式化函数,支持C++20编译时检查,依赖最小化。
    • fmt/format.h:完整的格式化API,除了额外的格式化函数之外,支持本地化(多语言支持)。
    • fmt/ranges.h:格式化ranges 和 tuples
    • fmt/chrono.h:日期和时间的格式化。
    • fmt/std.h:c++标准库类型的格式化支持。
    • fmt/compile.h:格式化字符串的编译 (编译时格式化字符串检测)。FMT_STRING(s)
    • fmt/color.h:终端颜色和文本样式。
    • fmt/os.h:提供系统API。
    • fmt/ostream.h:支持std::ostream。
    • fmt/printf.h:支持printf格式化。
    • fmt/xchar.h:可选的wchar_t支持。
Hello World
    #define FMT_HEADER_ONLY 
    #include "fmt/core.h"
    #include <string>
    int main()
    {
        // {} 占位符,可以占位int float double ....
        std::string world = fmt::format("Hello {}", "World");
        fmt::print("{}", world);
    }

三、 字符格式化语法

格式化函数如 fmt::format() 和 fmt::print() 都使用相同的语法,它由 {} 包围的“替换字段”。
未包含在花括号中的任何内容都被视为文字文本,将不加修改地复制到输出中。果需要在字面文本中包含一个花括号字符,可以通过重复使用花括号来转义:{{ 和 }}。
在大多数情况下,语法与 printf 格式相似,但添加了 {} 并使用 : 代替 %。例如,“%03.2f” 可以转换为 “{:03.2f}”,只是把%替换了{} 但是fmt功能更强大
输出格式如下:
replacement_field ::= “{” [arg_id] [“:” (format_spec | chrono_format_spec)] “}” // 替换字符= {[参数id]:[format_spec] | [chrono_format_spec]}
arg_id ::= integer | identifier // 整数0-9 a-z A-Z, 下面的是表示哪个代表什么意思
integer ::= digit+
digit ::= “0”…“9”
identifier ::= id_start id_continue*
id_start ::= “a”…“z” | “A”…“Z” | “_”
id_continue ::= id_start | digit\

替换格式以 “:” 为分界符,“:” 前面的的代表参数id, 就是指参数的顺序,可以是1、2、3、4、… 也可以是a、b 、c … “:” 后面的就是专门针对数字型(整形、浮动点型) 时间类型定义的格式。[] 代表是可选的, | 代表或,只能存在一种

3.1参数id 在":" 之前
    // 只有参数id时候,: 可以省略不写
    fmt::print("name:{1}, age: {0:}", 42, "knox");
3.2format_spec 在":" 之后 (Format Specification Mini-Language 格式化规范迷你语言)
  1. 组成
    format_spec ::= [[fill]align][sign][“#”][“0”][width][“.” precision][“L”][type]
    fill ::= <a character other than ‘{’ or ‘}’>
    align ::= “<” | “>” | “^”
    sign ::= “+” | “-” | " "
    width ::= integer | “{” [arg_id] “}”
    precision ::= integer | “{” [arg_id] “}”
    type ::= “a” | “A” | “b” | “B” | “c” | “d” | “e” | “E” | “f” | “F” | “g” | “G” |
    “o” | “p” | “s” | “x” | “X”\

  2. file 代表填充字符,填充字符可以是除了“{”和“}”之外的任何 Unicode 代码点。填充字符的存在是由其后面的字符表示的,该字符必须是对齐选项之一。如果 format_spec 的第二个字符不是有效的对齐选项(<、>、^),则假定填充字符和对齐选项都不存在。

  3. align 代表对其方式 ,< 代表左对齐, >代表右对齐, ^代表居中

  4. sign 只针对数字,“+”表示正数和负数都要使用符号。“-”表示只有负数需要使用符号(这是默认行为)。空格表示正数前面要加一个空格,负数前面要加一个减号。

  5. 此选项仅适用于整数和浮点数类型。对于整数,当使用二进制、八进制或十六进制输出时,此选项会将相应的前缀“0b”(“0B”)、“0”或“0x”(“0X”)添加到输出值中, 小写字符格式出来的是小写,如,{:#0X}, 255 = 0XFF, ,{:#0x}, 255 = 0xff, 其他的进制类似,

  6. width 十进制的整数,只适用于数值型,用于定义最小字段宽度。如果未指定,则字段宽度将由内容确定。在宽度字段之前加上零(‘0’)字符可以启用数值类型的符号感知零填充。
    它强制在符号或基数(如果有)之后但在数字之前放置填充。这用于以“+000000120”形式打印字段。

  7. “.” precision 代表精度。精度只存在于 浮点型中,整数、字符、布尔和指针值,是不允许使用精度的,对于非数字类型,字段指示最大字段大小,就算指定了大小。C字符串必须以空字符结尾.
    一般精度.nf, 不是精度.n n代表需要格式化几个。

    // 非数字指定的是输出的字符的个数。
    fmt::print("name:{1}, age: {0:.5}", "1234567890", "knox");
    // 输出:name:knox, age: 12345
    
    // c字符串不够怎么办呢,最大字符串长
    fmt::print("name:{1}, age: {0:.5}", "123", "knox");
    // 输出:name:knox, age: 123
    
    // 对于数字代表精度,只对浮点型有用
    fmt::print("{:.2f}", 42.0f);
    // 输出:42.00
    //fmt::print("{:.2f}", 42); 编译报错
    //fmt::print("{:.2f}", true); 编译报错

  1. “L”选项使用当前区域设置来插入适当的数字分隔符。此选项仅适用于数值类型。
    auto s = fmt::format(std::locale("en_US.UTF-8"), "{:L}", 1234567890);
    fmt::print("{}", s);
    // 输出: 1,234,567,890
  1. type
    'e’指数表示法。指数标记使用小写字母 ‘e’。
    'E’指数表示法。指数标记使用大写字母 ‘E’。
    'f’定点表示法。将数字显示为定点数。
    'F’定点表示法。将数字显示为定点数。与 ‘f’ 相同。
    'g’通用格式。根据数字的大小和指定的精度,使用定点表示法或指数表示法。
    'G’通用格式。与 ‘g’ 相同,但使用指数标记使用大写字母 ‘E’。
    'x’十六进制整数。将数字显示为十六进制数。
    'X’十六进制整数。将数字显示为大写十六进制数。
    'a’十六进制浮点数。使用小写字母 ‘a’ 作为指数标记。
    'A’十六进制浮点数。使用大写字母 ‘A’ 作为指数标记。
    'c’字符。将整数解释为 Unicode 字符。
    's’字符串。将参数格式化为字符串。
    'p’指针。将指针格式化为十六进制数。
chrono_format_spec 时间格式化

1.组成
chrono_format_spec ::= [[fill]align][width][“.” precision][chrono_specs]
chrono_specs ::= [chrono_specs] conversion_spec | chrono_specs literal_char
conversion_spec ::= “%” [modifier] chrono_type
literal_char ::= <a character other than ‘{’, ‘}’ or ‘%’>\ // 除了{ } % 这三个字符都可以做链接符
modifier ::= “E” | “O”
chrono_type ::= “a” | “A” | “b” | “B” | “c” | “C” | “d” | “D” | “e” | “F” |
“g” | “G” | “h” | “H” | “I” | “j” | “m” | “M” | “n” | “p” |
“q” | “Q” | “r” | “R” | “S” | “t” | “T” | “u” | “U” | “V” |
“w” | “W” | “x” | “X” | “y” | “Y” | “z” | “Z” | “%”\

  1. [[fill]align] 与3.2.1 相似
  2. 天数小于10,分钟数,秒数,月数,都会在前面添加0
    关于fmt 格式化字符串更详细的语法请移步https://fmt.dev/latest/syntax.html#grammar-token-sf-identifier
格式化字符串示例
按arg_id 顺序输出,id从0开始
    // 序号从零开始
    fmt::print("{0}, {1}, {2}\n", 'a', 'b', 'c');
    // print: "a, b, c"


    fmt::print("{}, {}, {}\n", 'a', 'b', 'c');
    // print: "a, b, c"

    fmt::print("{2}, {1}, {0} \n", 'a', 'b', 'c');
    // print: "c, b, a"
    // fmt::print("{2}, {1}, {0} {3}\n", 'a', 'b', 'c'); 编译报错,没有第四个参数

    // 输出
    // a, b, c  
    // a, b, c  
    // c, b, a  
用自定的字符填充空白符,并指定居中方式
    // 不指定填充符号默认为空格, 如果不存在 <>^ 就假定填充符号都不存在
    fmt::print("{:<30}\n", "left aligned");
    // 
    fmt::print("{:<<30}\n", "left aligned");
                
    fmt::print("{:>30}\n", "right aligned");
    fmt::print("{:>>30}\n", "right aligned");

    fmt::print("{:^30}\n", "centered");
          
    fmt::print("{:^^30}\n", "centered"); 

    // 输出
    //left aligned                  
    //left aligned<<<<<<<<<<<<<<<<<<
    //                right aligned 
    //>>>>>>>>>>>>>>>>>right aligned
    //        centered              
    //^^^^^^^^^^^centered^^^^^^^^^^^

动态设置宽度和精度
    // 可以动态设置宽度和精度,但仅仅限制于此,
    // 动态设置宽度的时候,宽度arg_id 为 参数+1, 
    //           0 1   2 3  参数arg_id 可以数{ 的个数,当然{} 一定是成对出现的。
    fmt::print("{:<{}} {:.{}f} \n", "left aligned", 30, 3.14, 1);
    fmt::print("{:.{}f}\n", 3.14, 1);
    // 输出
    // left aligned                   3.1  
    // 3.1  

:+ :- 号的使用
    // + 代表正数加+号,负数加-号
    fmt::print("{:+f}; {:+f}\n", 3.14, -3.14); 
    // 空格正数加空格,负数加-号
    fmt::print("{: f}; {: f}\n", 3.14, -3.14); 
    // -号代表正数不变,负数加-号 same as '{:f}; {:f}' 相当于是默认行为
    fmt::print("{:-f}; {:-f}\n", 3.14, -3.14);

    fmt::print("{:+}; {:+}\n", 3, -3);
    fmt::print("{:-}; {:-}\n", 3, -3);
    fmt::print("{: }; {: }\n", 3, -3);
    fmt::print("{:}; {:}\n", 3, -3);

    // 输出
    //+3.140000; -3.140000
    // 3.140000; -3.140000
    //3.140000; -3.140000
    //+3; -3
    //3; -3
    // 3; -3
    //3; -3
进制输出
    // # 加上符号 0x 0 0b
    fmt::print("int: {0:d};  hex: {0:x};  oct: {0:o}; bin: {0:b}\n", 42);
    
    fmt::print("int: {0:d};  hex: {0:#x};  oct: {0:#o};  bin: {0:#b}\n", 42);

    // #06 代表宽度为6个, 不够的在进制之前使用0填充, 超出指定大小被忽略
    fmt::print("int: {0:d};  hex: {0:#06x};  oct: {0:#06o};  bin: {0:#06b}\n", 42);
    fmt::print("int: {0:d};  hex: {0:#01x};  oct: {0:#02o};  bin: {0:#03b}\n", 42);
    // 输出
    // int: 42;  hex: 2a;  oct: 52; bin: 101010
    // int: 42;  hex: 0x2a;  oct: 052;  bin: 0b101010
    // int: 42;  hex: 0x002a;  oct: 000052;  bin: 0b101010
    // int: 42;  hex: 0x2a;  oct: 052;  bin: 0b101010
使用填充字符打印边框
    fmt::print(
        "┌{0:─^{2}}┐\n"
        "│{1: ^{2}}│\n"
        "└{0:─^{2}}┘\n", "", "Hello, knox!", 20);

有点抗不住了,今天就先到这里了,明天我们继续刚fmt库的api详细用法。文章来源地址https://www.toymoban.com/news/detail-558991.html

到了这里,关于c++ {fmt}库使用指南一的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • M1Mac 使用 qemu 配置 archlinux 虚拟机的完整c++开发环境与踩坑指南

    之前写了关于 qemu 安装 archlinux 的文章, 但是还有一些内容没得到解决, 比如很多时候 ssh 连接不成功, 这时候用图形界面(默认选项)的优势就体现出来了, 并且如果需要传输文件或者需要使用对外的端口, 仅转发一个22端口是不够的, 最后就是 gdb 调试的整套环境的配置, 这些问题

    2024年02月06日
    浏览(42)
  • 11-3_Qt 5.9 C++开发指南_QSqlQuery的使用(QSqlQuery 是能执行任意 SQL 语句的类)

    QSqlQuery 是能执行任意 SQL 语句的类,如 SELECT、INSERT、UPDATE、DELETE 等,QSqlQuery 类的一些常用函数见表 11-11(省略函数中的 const ,省略缺省参数,不同参数的同名函数一般只给出一种参数形式)。 使用 QSqlQuery 执行不带参数的 SQL 语句时可以用 exec(QString)函数,如: 上面是

    2024年02月15日
    浏览(42)
  • 16-3_Qt 5.9 C++开发指南_使用QStyle 设置界面外观_实现不同系统下的界面效果的匹配

    Qt 是一个跨平台的类库,相同的界面组件在不同的操作系统上显示效果是不一样的。QStyle是封装了 GUI 界面组件外观的抽象类,Qt 定义了 QStyle 类的一些子类,应用于不同的操作系统如QWindowsStyle和QMacStyle 等。这些样式是 QtGUI 模块自带的,在不同的平台上编译运行的程序具有缺

    2024年02月13日
    浏览(40)
  • 07-1_Qt 5.9 C++开发指南_文件系统及文件读写_文本文件读写(使用 QTextStream 进行文件读写更为方便)

    文本文件是指以纯文本格式存储的文件,例如用 Qt Creator 编写的 C++程序的头文件 (.h 文件)和源程序文件 (.cpp 文件)。HTML 和 XML 文件也是纯文本文件,只是其读取之后需要对内容进行解析之后再显示。 Qt 提供了两种读写纯文本文件的基本方法, 一种是用 QFile 类的 IODevice 读写

    2024年02月13日
    浏览(42)
  • 使用C++播放声音的完整指南

    首先,我们需要选择一个合适的音频库。在C++中,常用的音频库有OpenAL、SDL和SFML等。这里我们选择使用SFML库,因为它易于使用且跨平台性好。 2. 安装SFML库: 在开始之前,请确保已经安装了SFML库。你可以从SFML的官方网站(https://www.sfml-dev.org/)下载并安装适合你的操作系统

    2024年01月19日
    浏览(24)
  • 【C++杂货铺】string使用指南

    2024年02月14日
    浏览(33)
  • C++ max和min函数详细使用指南

    C++ 是一种强大而灵活的编程语言,具有丰富的标准库,其中包括了一系列实用的函数。其中, max 和 min 函数是处理数值的时候经常用到的工具。本文将深入探讨这两个函数的使用方法,以及它们在不同情景下的应用。 首先,让我们来看一下 max 函数。该函数用于获取一组值

    2024年01月25日
    浏览(35)
  • C++ STL之list接口的详细使用指南

    本文详细介绍了C++ STL中list接口的使用,包括list的基本特性、底层结构、与其他容器的比较,以及各种操作方法如插入、删除、迭代、排序等。通过阅读本文,您将对C++中的list有更深入的理解。

    2024年02月13日
    浏览(66)
  • C++ 中的原子变量(std::atomic)使用指南

    原子变量( std::atomic )是C++中用于多线程编程的强大工具之一。它们提供了一种线程安全的方式来访问和修改共享数据,而无需使用显式的互斥锁。本文将介绍 std::atomic 的基本概念、使用方法、常见应用场景以及示例代码,适合入门级读者。 原子变量是一种特殊的数据类型

    2024年01月21日
    浏览(35)
  • 小程序开发:开发框架与工具的使用指南

    本文以微信小程序为例介绍了小程序开发框架与工具的使用,通过本文的阅读,相信大家能够简单了解小程序开发的基本流程和常用工具,从而快速上手小程序开发。 1.1 小程序开发框架 小程序开发框架是一套用于快速构建小程序的开发框架,提供了丰富的组件和API,使得开

    2024年02月14日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包