0%

C++格式化输出库fmt

用 C++ 来拼接一个字符串非常糟心,虽然说你可以用 stringstream 来做到,但是无数的 << 就很麻烦,而 printf 也是一样。(囧,我一般都是直接使用日志打印)

1
2
3
4
5
6
7
8
9
10
printf 函数家族声明如下:
// https://en.cppreference.com/w/cpp/header/cstdio
int printf( const char* format, ... );
int fprintf(std::FILE* stream, const char* format, ... );
int sprintf( char* buffer, const char* format, ... );
int snprintf( char* buffer, std::size_t buf_size, const char* format, ... );
int vprintf( const char* format, va_list vlist );
int vfprintf( std::FILE* stream, const char* format, va_list vlist );
int vsprintf( char* buffer, const char* format, va_list vlist );
int vsnprintf( char* buffer, std::size_t buf_size, const char* format, va_list vlist );

C++中printf的一个很好的替代品是fmtlib,其也进入了C++20的标准库(std::format),可以算是C++字符串格式化的未来。

fmtlib可以直接使用header-only的方法使用,cmake配置如下

1
2
add_subdirectory(dependencies/fmt EXCLUDE_FROM_ALL)
target_link_libraries(fmt_demo fmt-header-only)
  • 其中 EXCLUDE_FROM_ALL表示将这个项目移除出 make 列表。

两个有意思的用法

Format a string using positional arguments

1
2
std::string s = fmt::format("I'd rather be {1} than {0}.", "right", "happy");
// s == "I'd rather be happy than right."
  • Check a format string at compile time
1
std::string s = fmt::format(FMT_STRING("{:d}"), "I am not a number");