fmt 库用法简介

C++ 的 fmt 库是一个开源、轻量和高性能的格式化库,它实现了 C++20 的 std::format 标准,用来替代 C 中的 stdio 和 C++ 的 iostream

fmt 库 的性能相比于 printfiostream 有显著的提升,经过官方文档测试,速度分别快 0.34 倍,且该库提供了类似 Python 的字符串格式化语法,使用起来非常容易上手,在具备高效率和易用性的同时,fmt 也是完全类型安全地,可以在编译时报告格式字符串中的错误,其自动内存管理亦可防止缓冲区溢出错误。

fmt 库使用较为简单,常用的函数有两个: fmt::printfmt::format。该库可以直接在 PowerShell 中通过 vcpkg 用下面命令进行安装:

.\vcpkg install fmt:x64-windows

一、fmt::print 函数

该函数用于直接将数据进行格式化并输出到控制台。

1 打印整型数据

需要 #include <fmt/core.h>

// 基本上同 printf 中的类型,d 表示整数、f/F/g/G/e/E 表示浮点数,
// s 表示字符串,p 表示指针,b/B/o/x/X 用二/八/十六进制表示整数
fmt::print("整型数据:{0:d} {1:d}\r\n\n", 100, 101);    // 0 指第一个参数,1 指第二个参数,可省略

结果如下:

2 打印浮点型数据

fmt::print("PI is {:.2f}\r\n", 3.1415926);    // 保留小数点后两位,".2f" 前面 的 ':' 是一个特殊的标记,用来引入格式化说明符
fmt::print("PI is {:>10.2f}\r\n", 3.1415926);    // 10 个字符宽度,右对齐(不足的用空格填充在左侧)
fmt::print("PI is {:<10.2f}\r\n", 3.1415926);    // 10 个字符宽度,左对齐(不足的用空格填充在右侧)
fmt::print("PI is {:^10.2f}\r\n", 3.1415926);    // 10 个字符宽度,居中对齐(不足的用空格填充在两侧)
fmt::print("PI is {:*^10.2f}\r\n\n", 3.1415926);    // 10 个字符宽度,居中对齐(不足的用 `*` 字符填充在两侧)

结果如下:

3 打印布尔型数据

fmt::print("{}\r\n\n", true);

结果如下:

4 打印 vector

需要 #include <vector>、<fmt/core.h>、<fmt/ranges.h>

fmt::print("vec: {}\r\n\n", std::vector<int>{1, 4, 7});

结果如下:

5 设置控制台输出的文本样式

需要 #include <fmt/core.h>、<fmt/color.h>

fmt::print(fg(fmt::color::red) | fmt::emphasis::bold, 
    "Hello, World!\r\n");    // 设置前景色(文字颜色)为红色,且文本样式为加粗
fmt::print(fg(fmt::color::white) | bg(fmt::color::gray) | fmt::emphasis::underline, 
    "Hello, World!\r\n");    // 设置前景色为白色、背景色为灰色,且文本样式为下划线
fmt::print(fg(fmt::color::blue) | fmt::emphasis::italic, 
    "Hello, World!\r\n\n");    // 设置前景色为蓝色,且文本样式为斜体

结果如下:

6 打印格式化时间

需要 #include <fmt/core.h>、<fmt/chrono.h>、<chrono>、<ctime>

auto now = std::chrono::system_clock::now();    // 获取 Unix 纳秒时间(1970 年 1月 1 日 00::00::00 UTC)
std::time_t now_c = std::chrono::system_clock::to_time_t(now);    // 将纳秒时间转为秒(UTC)
fmt::print("Current time(UTC: s): {}\r\n", now_c);
fmt::print("Current time(Local: formatted): {:%Y-%m-%d %H:%M:%S}\r\n\n", fmt::localtime(now_c));

结果如下:

7 格式化输出到文件

fmt::print 主要关注格式化输出到控制台,其他更多的文件输入与输出操作可以使用 C++ 标准库中的文件流结合 fmt::format 来实现:

auto fout = fmt::output_file("output.txt");  // 默认以写入模式打开文件
fout.print("The value of pi is approximately {:.2f}.\r\n", 3.14159);
fout.close();

结果如下:

二、fmt::format 函数

该函数通过格式化数据,返回 std::string 类型方便处理。

1 格式化打印 vector 中结构体数据

需要 #include <fmt/format.h>

struct Person
{
    std::string name;
    int age;
};

std::vector<Person> people =
{
    {"Alice", 18},
    {"Bob", 19},
    {"Tom", 20}
};

std::string output;
for (const auto& person : people)
{
    output += fmt::format("Name: {0:<10} | Age: {1}\r\n", person.name, person.age);
}
fmt::print("List of people:\n{}\n", output);

结果如下:

2 结合输入输出流操作读写文件

需要 #include <fstream>、<fmt/format.h>

	std::ofstream ofs("output.txt", std::ios::out | std::ios::app);
	if (ofs.is_open())
	{
		for (int i = 0; i < 2; ++i)
		{
			ofs << fmt::format("The value is {:d}.\r\n", i);
		}
		ofs.close();
	}

	std::ifstream ifs("output.txt");
	if (ifs.is_open())
	{
		std::string line;
		while (std::getline(ifs, line))
		{
			fmt::print("{}\r\n", line);
		}
		ifs.close();
	}

结果如下:

posted @ 2024-12-06 19:31  lostin9772  阅读(114)  评论(0)    收藏  举报