!!版权声明:本文为博主原创文章,版权归原文作者和博客园共有,谢绝任何形式的 转载!!

作者:mohist

fmt 源码: https://github.com/fmtlib/fmt

fmt官方文档: https://fmt.dev/latest/index.html#compact-binary-code

本文源自对官方文档的理解。

本文使用 fmt version: 7.0.1

-----------------> <---------------------

1、准备:

  A、下载源码,使用cmake配置生成VS解决方案

  B、编译成功的动态库fmt 文件: .dll  + .lib

 

2、使用

  这里演示,创建了一个空的项目,添加了一个main.cpp文件,文件内容如下:

  添加fmt头文件:

#include "3rd_part/fmt/core.h"

  链接lib文件

#pragma comment(lib, "lib/fmtd.lib")

3、示例

  A、fmt::format 返回一个字符串

auto str = fmt::format("1、{0} = {1}\n\n", "1+1", 2);

  B、使用 fmt::memory_buffer 可以避免构造使用string

    fmt::memory_buffer out;
format_to(out, "2、For a moment, {} happened.\n\n", "nothing");
// 这里输出的也是一个char字符串
fmt::print(out.data());

  注意,使用 fmt::memory_buffer 需要额外包含头文件:

// 使用 memory_buffer 包含的头文件
#include "3rd_part/fmt/format.h"

  C、fmt::print输出结果

    auto err_no = 1;
fmt::print(stderr, "3、System error code = {}\n\n", err_no);
fmt::print("3、Don't {}\n\n", "panic");

  D、 Format API也支持设置位置索引(格式化)

fmt::print("4、I'd rather be {1} than {0}.\n\n", "right", "happy");

  E、可以使用fmt::arg指定替换参数的值, 这样就可以很清晰的知道每个参数的值

    fmt::print("5、Hello, {name}! The answer is {number}. Goodbye, {name}.\n\n",
fmt::arg("name", "World"),
fmt::arg("number", 99) );

  F、若编译器支持c++ 11用户自定义的文本, 后缀 _a提供了一种可以选。 更加简明的语法示例如下:

fmt::print("6、Hello, {name}! The answer is {number}. Goodbye, {name}.\n\n",
"name"_a = "World",
"number"_a = 42);

  

3、其他

  fmt的类型是安全的。 自动内存管理避免了内存泄漏的情况,使用 异常捕获 或者在编译时提示格式化字符串中的错误。例如:

fmt::format("The answer is {:d}", "forty-two");上面的代码将会抛出异常: format_error 。 format_error的内容:未知的格式字符格式‘d’

  因为 "forty-two" 是一个字符串, 而 格式化字符串中‘d’仅仅表示接收的是一个整数。

  

  下面的代码 在编译的时候会抛出一个错误,原因和上面是一样的,

 format(FMT_STRING("The answer is {:d}"), "forty-two");

  

4、宽字符的格式化

  下面的代码, 当编译时,也会抛出一个错误, 因为 宽字符 L'\x42e'无法格式为一个普通字符串。

fmt::format("Cyrillic letter {}", L'\x42e');

  若需要使用宽字符, 可以使用下面的方法,格式化得到一个宽字符的字符串。 注意:格式化 字符串中多了一个 【L】 

fmt::format(L"Cyrillic letter {}", L'\x42e');

----------------------------------------------------------------------------------------------

main.cpp的完整源码如下:

#include "3rd_part/fmt/core.h"

// -------------------------------------------------------------------------------
// 使用 memory_buffer 包含的头文件
#include "3rd_part/fmt/format.h" #include <string>
#include <iostream> // _a前缀必须引用的命名空间
using namespace fmt::literals; #pragma comment(lib, "lib/fmtd.lib") int main(int argc, char * argv[])
{ // 1、fmt::format 返回一个字符串
auto str = fmt::format("1、{0} = {1}\n\n", "1+1", 2);
std::cout << str << std::endl; // 2、使用 fmt::memory_buffer 可以避免构造使用string
fmt::memory_buffer out;
format_to(out, "2、For a moment, {} happened.\n\n", "nothing");
// 这里输出的也是一个char字符串
fmt::print(out.data()); // 3、fmt::print输出结果
auto err_no = 1;
fmt::print(stderr, "3、System error code = {}\n\n", err_no);
fmt::print("3、Don't {}\n\n", "panic"); // 4、Format API也支持设置位置索引(格式化)
fmt::print("4、I'd rather be {1} than {0}.\n\n", "right", "happy"); // 5、可以使用fmt::arg指定替换参数的值, 这样就可以很清晰的知道每个参数的值
fmt::print("5、Hello, {name}! The answer is {number}. Goodbye, {name}.\n\n",
fmt::arg("name", "World"),
fmt::arg("number", 99) ); // 6、若编译器支持c++ 11用户自定义的文本, 后缀 _a提供了一种可以选。 更加简明的语法示例如下:
fmt::print("6、Hello, {name}! The answer is {number}. Goodbye, {name}.\n\n",
"name"_a = "World",
"number"_a = 42); // ------------------------------------------------------------------------------- // 7、fmt的类型是安全的。 自动内存管理避免了内存泄漏的情况,使用 异常捕获 或者在编译时提示格式化字符串中的错误。例如:
// fmt::format("The answer is {:d}", "forty-two");
// 上面的代码将会抛出异常: format_error 。 format_error的内容:未知的格式字符格式‘d’
// 因为 "forty-two" 是一个字符串, 而 格式化字符串中‘d’仅仅表示接收的是一个整数。 // 下面的代码 在编译的时候会抛出一个错误,原因和上面是一样的,
// format(FMT_STRING("The answer is {:d}"), "forty-two"); // -------------------------------------------------------------------------------
// 8、下面的代码, 当编译时,也会抛出一个错误, 因为 宽字符 L'\x42e'无法格式为一个普通字符串。
// fmt::format("Cyrillic letter {}", L'\x42e');
// 若需要使用宽字符, 可以使用下面的方法,格式化得到一个宽字符的字符串。 注意:格式化 字符串中多了一个 【L】
fmt::format(L"Cyrillic letter {}", L'\x42e'); system("pause");
return 0;
}

  编译输出结果:

:D  完。

继续阅读文档与源码

最新文章

  1. winform最小化后隐藏到右下角,单击或双击后恢复 .
  2. winform 窗体移动API、窗体阴影API
  3. nova分析(9)—— nova-novncproxy
  4. TDD 用语
  5. Lucene.Net 2.3.1开发介绍 —— 一、接触Lucene.Net
  6. equals和hashcode为什么要一起重写
  7. aforge 学习-基本图像处理要用的类库
  8. 微信小程序(七)文章详情页面动态显示
  9. Shell脚本2
  10. jsp一些使用技巧
  11. python接口自动化测试二十六:使用pymysql模块链接数据库
  12. 安装MySQL半同步复制
  13. (转发)一个通用的C++ 消息总线框架
  14. 004 作业二(单击弹跳li节点的每个文本节点的值;点击每个 li 节点, 若 li 节点的文本值没有 ^^ 开头, 加上,有,则去除)
  15. centos7/nginx/tornado错误异常收集
  16. c语言中的0UL或1UL是什么意思
  17. css布局中关于 块状元素和行内元素的区分
  18. C#中的类
  19. NSArray最简单的倒序
  20. MySQL5.7 半同步复制

热门文章

  1. Codeforces 1188D - Make Equal(dp)
  2. 富集分析DAVID、Metascape、Enrichr、ClueGO
  3. mysql 计算日期为当年第几季度
  4. ZooKeeper 04 - ZooKeeper 集群的节点为什么必须是奇数个
  5. 面对大规模 K8s 集群,这款诊断利器必须要“粉一波”!
  6. 【leetocde】922. Sort Array By Parity II
  7. Playing with Destructors in C++
  8. js将数字转为千分位/清除千分位
  9. Hystrix断路器中的服务熔断与服务降级
  10. SQL 父子表,显示表中每条记录所在层级