C++ string格式化输出
flyfish
C++ std::string格式化输出 需要分情况
如果是 C++20 可以是std::format
如果是 C++23 可以是std::print
如果是C++17 以下包括17 可以使用使用 Boost C++ 库中的 Boost.Format或者 fmt库
fmt 库的主要特点
下载地址 https://github.com/fmtlib/fmt
简单的格式化 API:带有位置参数的简单格式化 API 适用于本地化。
C++20 标准库 std::format 和 C++23 标准库 std::print 的实现。
格式字符串语法:类似于 Python 的格式化字符串语法。
快速的 IEEE 754 浮点数格式化:使用 Dragonbox 算法实现了正确的舍入、最短表示和往返保证。
便携式的 Unicode 支持。
安全的 printf 实现:包括 POSIX 扩展的位置参数支持。
可扩展性:支持用户自定义类型。
高性能:比常见的标准库实现的 (s)printf、iostreams、to_string 和 to_chars 更快;参见速度测试以及每秒转换一亿个整数为字符串的演示。
小代码量:无论是从源代码还是编译后的代码来看都很小;最小配置仅包含三个文件:core.h、format.h 和 format-inl.h;参见编译时间和代码膨胀。
可靠性:该库具有广泛的测试集,并持续进行模糊测试。
安全性:完全类型安全,可以在编译时报告格式字符串中的错误;自动内存管理防止缓冲区溢出错误。
易于使用:小型自包含代码库,没有外部依赖项,采用宽松的 MIT 许可证。
可移植性:跨平台一致的输出和支持旧版编译器。
无警告的代码库:即使在高警告级别下(如 -Wall -Wextra -pedantic)也能保持干净无警告。
默认的本地独立性。
可选的纯头文件配置:通过 FMT_HEADER_ONLY 宏启用
C++ 20的例子
基本使用
#include <iostream>
#include <format>
int main() {
std::string name = "flyfish";
int age = 30;
// 格式化输出字符串
std::string formattedString = std::format("Hello, {}! Your age is {}", name, age);
std::cout << formattedString << std::endl;
return 0;
}
输出
Hello, flyfish! Your age is 30
十六进制和八进制格式化
#include <iostream>
#include <format>
int main() {
int number = 255;
// 十六进制格式化输出,不带前缀
std::string hexString = std::format("Hexadecimal: {:x}", number);
std::cout << hexString << std::endl;
// 十六进制格式化输出,带前缀
std::string hexStringWithPrefix = std::format("Hexadecimal with prefix: {:#x}", number);
std::cout << hexStringWithPrefix << std::endl;
// 八进制格式化输出,不带前缀
std::string octString = std::format("Octal: {:o}", number);
std::cout << octString << std::endl;
// 八进制格式化输出,带前缀
std::string octStringWithPrefix = std::format("Octal with prefix: {:#o}", number);
std::cout << octStringWithPrefix << std::endl;
return 0;
}
输出
Hexadecimal: ff
Hexadecimal with prefix: 0xff
Octal: 377
Octal with prefix: 0377
带有前导零和指定宽度的格式化
#include <iostream>
#include <format>
int main() {
int number = 255;
// 十六进制格式化输出,至少8位宽,带前导零
std::string hexStringWithLeadingZeros = std::format("Hexadecimal with leading zeros: {:08x}", number);
std::cout << hexStringWithLeadingZeros << std::endl;
// 十六进制格式化输出,至少8位宽,带前导空格
std::string hexStringWithLeadingSpaces = std::format("Hexadecimal with leading spaces: {:8x}", number);
std::cout << hexStringWithLeadingSpaces << std::endl;
// 八进制格式化输出,至少8位宽,带前导零
std::string octStringWithLeadingZeros = std::format("Octal with leading zeros: {:08o}", number);
std::cout << octStringWithLeadingZeros << std::endl;
// 八进制格式化输出,至少8位宽,带前导空格
std::string octStringWithLeadingSpaces = std::format("Octal with leading spaces: {:8o}", number);
std::cout << octStringWithLeadingSpaces << std::endl;
return 0;
}
输出
Hexadecimal with leading zeros: 000000ff
Hexadecimal with leading spaces: ff
Octal with leading zeros: 00000377
Octal with leading spaces: 377
浮点数格式化
#include <iostream>
#include <format>
int main() {
double pi = 3.141592653589793;
// 默认浮点数格式化输出
std::string defaultFloat = std::format("Default float: {}", pi);
std::cout << defaultFloat << std::endl;
// 指定小数点后两位
std::string twoDecimalPlaces = std::format("Two decimal places: {:.2f}", pi);
std::cout << twoDecimalPlaces << std::endl;
// 科学计数法格式化输出
std::string scientific = std::format("Scientific notation: {:e}", pi);
std::cout << scientific << std::endl;
// 指定宽度和对齐方式
std::string widthAndAlign = std::format("Width 10, align right: {:>10.2f}", pi);
std::cout << widthAndAlign << std::endl;
// 指定宽度和填充字符
std::string widthAndFill = std::format("Width 10, fill with *: {:*>10.2f}", pi);
std::cout << widthAndFill << std::endl;
return 0;
}
输出
Default float: 3.141592653589793
Two decimal places: 3.14
Scientific notation: 3.141593e+00
Width 10, align right: 3.14
Width 10, fill with *: ******3.14
字符串格式化和对齐
#include <iostream>
#include <format>
int main() {
std::string text = "Hello";
// 默认字符串格式化输出
std::string defaultString = std::format("Default string: {}", text);
std::cout << defaultString << std::endl;
// 指定宽度和左对齐
std::string leftAlign = std::format("Left aligned: {:<10}", text);
std::cout << leftAlign << std::endl;
// 指定宽度和右对齐
std::string rightAlign = std::format("Right aligned: {:>10}", text);
std::cout << rightAlign << std::endl;
// 指定宽度和居中对齐
std::string centerAlign = std::format("Center aligned: {:^10}", text);
std::cout << centerAlign << std::endl;
// 指定宽度和填充字符
std::string widthAndFill = std::format("Width 10, fill with *: {:*^10}", text);
std::cout << widthAndFill << std::endl;
return 0;
}
输出
Default string: Hello
Left aligned: Hello
Right aligned: Hello
Center aligned: Hello
Width 10, fill with *: **Hello***
日期和时间格式化
#include <iostream>
#include <iomanip>
#include <ctime>
#include <sstream>
#include <format>
int main() {
auto now = std::time(nullptr);
auto tm = *std::localtime(&now);
// 使用 ostringstream 进行日期时间格式化
std::ostringstream dateStream;
dateStream << std::put_time(&tm, "%Y-%m-%d");
std::string formattedDate = dateStream.str();
std::ostringstream timeStream;
timeStream << std::put_time(&tm, "%H:%M:%S");
std::string formattedTime = timeStream.str();
// 使用 std::format 进行进一步格式化
std::string output = std::format("Formatted date: {} and time: {}", formattedDate, formattedTime);
std::cout << output << std::endl;
return 0;
}
C++ 17 的例子
如果不想使用第三方库
格式化整数
#include <iostream>
#include <sstream>
#include <iomanip>
int main() {
int number = 255;
// 十六进制格式化输出
std::ostringstream hexStream;
hexStream << std::hex << number;
std::cout << "Hexadecimal: " << hexStream.str() << std::endl;
// 带有前导零和指定宽度的十六进制格式化
std::ostringstream hexStreamWithLeadingZeros;
hexStreamWithLeadingZeros << std::setw(8) << std::setfill('0') << std::hex << number;
std::cout << "Hexadecimal with leading zeros: " << hexStreamWithLeadingZeros.str() << std::endl;
// 八进制格式化输出
std::ostringstream octStream;
octStream << std::oct << number;
std::cout << "Octal: " << octStream.str() << std::endl;
// 带有前导零和指定宽度的八进制格式化
std::ostringstream octStreamWithLeadingZeros;
octStreamWithLeadingZeros << std::setw(8) << std::setfill('0') << std::oct << number;
std::cout << "Octal with leading zeros: " << octStreamWithLeadingZeros.str() << std::endl;
return 0;
}
输出
Hexadecimal: ff
Hexadecimal with leading zeros: 000000ff
Octal: 377
Octal with leading zeros: 00000377
格式化浮点数
#include <iostream>
#include <sstream>
#include <iomanip>
int main() {
double pi = 3.141592653589793;
// 默认格式化输出
std::ostringstream defaultStream;
defaultStream << pi;
std::cout << "Default: " << defaultStream.str() << std::endl;
// 固定小数点格式化输出
std::ostringstream fixedStream;
fixedStream << std::fixed << std::setprecision(2) << pi;
std::cout << "Fixed: " << fixedStream.str() << std::endl;
// 科学计数法格式化输出
std::ostringstream scientificStream;
scientificStream << std::scientific << std::setprecision(2) << pi;
std::cout << "Scientific: " << scientificStream.str() << std::endl;
// 带有指定宽度和填充字符的浮点数格式化
std::ostringstream widthStream;
widthStream << std::setw(10) << std::setfill('*') << std::fixed << std::setprecision(2) << pi;
std::cout << "Width and fill: " << widthStream.str() << std::endl;
return 0;
}
输出
Default: 3.14159
Fixed: 3.14
Scientific: 3.14e+00
Width and fill: ******3.14
格式化字符串
#include <iostream>
#include <sstream>
#include <iomanip>
int main() {
std::string text = "Hello, world!";
// 默认格式化输出
std::ostringstream defaultStream;
defaultStream << text;
std::cout << "Default: " << defaultStream.str() << std::endl;
// 带有指定宽度和左对齐的字符串格式化
std::ostringstream leftAlignedStream;
leftAlignedStream << std::setw(20) << std::left << text;
std::cout << "Left aligned: " << leftAlignedStream.str() << std::endl;
// 带有指定宽度和右对齐的字符串格式化
std::ostringstream rightAlignedStream;
rightAlignedStream << std::setw(20) << std::right << text;
std::cout << "Right aligned: " << rightAlignedStream.str() << std::endl;
// 带有指定宽度和填充字符的字符串格式化
std::ostringstream fillStream;
fillStream << std::setw(20) << std::setfill('-') << text;
std::cout << "Width and fill: " << fillStream.str() << std::endl;
return 0;
}
输出
Default: Hello, world!
Left aligned: Hello, world!
Right aligned: Hello, world!
Width and fill: -------Hello, world!
格式化日期和时间
#include <iostream>
#include <sstream>
#include <iomanip>
#include <ctime>
int main() {
auto now = std::time(nullptr);
auto tm = *std::localtime(&now);
// 使用 ostringstream 进行日期时间格式化
std::ostringstream dateStream;
dateStream << std::put_time(&tm, "%Y-%m-%d");
std::cout << "Custom date: " << dateStream.str() << std::endl;
std::ostringstream timeStream;
timeStream << std::put_time(&tm, "%H:%M:%S");
std::cout << "Custom time: " << timeStream.str() << std::endl;
return 0;
}