boost之格式化format
传统的C语言printf,sprintf, 不会检查内存的边界,不安全。
-
头文件boost/format.hpp
-
编程中经常会遇到需要到使用的数据进行格式化的地方,如生成记录日志的字符串,生成发送到网络的完整数据等。
-
可能需要对int, string, char等进行格式化,常用的方法包括 snprintf, std::string, std::stringstream, boost::format等。
snprintf支持c语言,可能是这几种方式中效率最高的,它们之间的效率对比可以参考
https://www.boost.org/doc/libs/1_52_0/libs/spirit/doc/html/spirit/karma/performance_measurements/numeric_performance/format_performance.html
typedef basic_format<char> format;
- boost::format里的指示符语法大致有三大类:
-
- 继承并强化自printf的格式化字符串
形式为[ N$ ] [ flags ] [ width ] [ . precision ] type-char
N$可选,指定使用第N个参数(注意,要么所有指示符都加此参数,要么都不加)
接下来的参数可以参数printf的指示符,只是format为其中的flags添加了’_‘和’='标志,用于指出内部对齐和居中对齐。
- 继承并强化自printf的格式化字符串
-
- 设置打印规则,它是printf参数的一个补充,只是为了更直观点。
形式为:%|spec|
如:%|1$+5|表示显示第一个参数,显示正负号,宽度为5
- 设置打印规则,它是printf参数的一个补充,只是为了更直观点。
-
- 简单的位置标记
形式为:%N%
简单地声明显示第N个参数,优点是比较直观而且不用指定类型。
- 简单的位置标记
#include <iostream>
using namespace std;
#include<boost/format.hpp>
int main()
{
using boost::format;//使用format
//使用一
format fmt("%1% , %2% !!!"); //先定义对象
fmt % 123;
fmt % "hello";
cout << fmt << endl;
//使用二, 可以不按顺序,可以重复指定
format fmt2(" %2% ----- %1% ----- %2% !!!"); //先定义对象
fmt2 % 123;
fmt2 % "hello";
cout << fmt2 << endl;
//使用三, 可以重复使用
format fmt3(" %2% ----- %1% ----- %2% !!!");
fmt3 % 123;
fmt3 % "hello";
cout << fmt3 << endl;
fmt3 % 1.23456;
fmt3 % 'C';
cout << fmt3 << endl;
//用法四,链式使用
cout << format("****%1%****%2%!!!") % "hello" % 1.2345f << endl;
cout << (format("****%1%****%2%!!!") % "hello") % 1.2345f << endl;
//用法五,可以使用printf中的格式符
cout << format(" %d , %c ,%f , %s") % 666 % 'A' % 1.2345f % "Boost" << endl;
//N$指定用哪个参数
cout << format("---%2$s -----%1$s---") % "Boost" % "Hello" << endl;
//用法六,直接转为string
int age = 20;
const char* name = "zhangsan";
//替代sprintf
format fmt6("name: %1% age %2%");
fmt6% name% age;
string strStu = fmt6.str();//直接转为字符串
cout << strStu << endl;
return 0;
}
include <boost/format.hpp>
#include <iostream>
using namespace boost;
using namespace std;
// 格式输出控制,(类似c++准准库中的sprintf)
//
int main()
{
// format库的几种用法
//------------------------------------------
// 第一种:
// 最接近printf()
cout<< "First: " << format("%s: %d + % d = %d/n")%"sum"%1%2%(1+2); // format 重载了%操作符类似<<操作符
// result: sum: 1 + 2 =3
// 第二种:
// 在format对象中用%X%指定X是第几个参数
format fmt1("(%1% + %2%)*%2% = %3%/n"); // %1% 接收第一个参数, %2% 接收第二个参数, %3%接收第三个参数
fmt1 %2 %5; // 第一,二个参数
fmt1 %((2+5)*5); // 第三个参数,参数不一定像第一种方法直接植入,可以分次完成但参数的总数量不能少
cout<< "Second: " << fmt1.str(); // str()是获取格式化后的字符串,不负责清空
// result: (2 + 5)*5 = 50;
// 第三种:
// 带格式化选项(和printf一样)
format fmt3("%05d %-8.3f %10s %05X/n");
cout<< "Third: " <<fmt3 %62 %3.14159f %123456789 %48;
// 第四种:
// 在对象构造函数字符串添加管道符,用于美观
format fmt4("%|05d| %|-8.3f| %|10s| %|05X|/n");
cout<< "Fourth: " << fmt4 %62 %3.14159f %123456789 %48;
// 高级应用:
format fmtOther("%1% %2% %3% %2% %1%");
cout<< "Other normal: " << fmtOther %1 %2 %3 <<endl; // 插入值 %1%对应第一个参数,%2%第二个, %3%第三个
fmtOther.bind_arg(2, 10); // 将第二个参数固定为10,即使使用clear也一样
cout<< "Other bind_arg: " << fmtOther %1 %3 <<endl; // 插入值时忽略%2%,直接跳到下一个%X%
// group, modify_item 略
//-----------------------------
// 与printf的比较:
//-----------------------------
// printf是函数,format是类
// printf不进行类形检查,format进行类型安全检查
// printf速度是format的2到5倍
getchar();
return 0;
}