如何使用C++20格式化库输出到标准输出或文件?
C++20格式化输出到标准输出/文件流的替代方案
C20的<format>库确实只提供了字符串格式化能力,没有直接输出到流的接口,而C23的std::print又远水解不了近渴,下面是几个实用的解决办法:
1. 使用fmt库(最推荐)
fmt是C标准格式化库的原型,完全兼容C20的std::format,还额外提供了直接输出到流的fmt::print接口,用法和即将到来的std::print几乎一致,后续迁移到C++23成本极低。
示例代码:
#include <fmt/core.h> #include <fstream> // 输出到标准输出 fmt::print("Hello, {}!\n", "world"); // 输出到指定流(比如std::cout/cerr或文件流) std::ofstream output_file("example.txt"); fmt::print(output_file, "Pi is approximately {:.2f}\n", 3.14159);
fmt库可以通过包管理器(比如vcpkg、conan)快速安装,也可以直接下载源码集成到项目里,性能和易用性都拉满。
2. 自己封装流输出函数(纯C++20,无依赖)
如果不想引入第三方库,完全可以基于std::format封装一个简易的print函数,本质是先格式化出字符串再写入流,实现起来很简单:
#include <format> #include <ostream> #include <iostream> // 通用版本:输出到任意ostream template <typename... Args> void print(std::ostream& os, std::format_string<Args...> fmt, Args&&... args) { os << std::format(fmt, std::forward<Args>(args)...); } // 简化版本:默认输出到std::cout template <typename... Args> void print(std::format_string<Args...> fmt, Args&&... args) { print(std::cout, fmt, std::forward<Args>(args)...); }
使用示例:
// 输出到标准输出 print("Current value: {}\n", 42); // 输出到标准错误流 print(std::cerr, "Error code: {}\n", -1);
这种方式的缺点是会先生成完整的格式化字符串再输出,极端场景下性能略低于直接流式输出,但绝大多数日常开发场景完全够用。
3. 基于std::vformat的底层封装
如果需要更灵活的控制(比如处理可变参数列表),可以用std::vformat来实现底层的流输出逻辑:
#include <format> #include <ostream> #include <string_view> void print_to_stream(std::ostream& os, std::string_view fmt, std::format_args args) { os << std::vformat(fmt, args); } template <typename... Args> void print(std::ostream& os, std::format_string<Args...> fmt, Args&&... args) { print_to_stream(os, fmt.get(), std::make_format_args(std::forward<Args>(args)...)); } // 同样可以加一个默认输出到cout的重载 template <typename... Args> void print(std::format_string<Args...> fmt, Args&&... args) { print(std::cout, fmt, std::forward<Args>(args)...); }
这个方案和第二种类似,但更贴近标准库的底层接口,适合需要自定义扩展的场景。
内容的提问来源于stack exchange,提问作者dgnuff
相关产品推荐
相关产品推荐

