本文共 8331 字,大约阅读时间需要 27 分钟。
来源:
boost::format的格式一般为:
boost::format( "format-string ") % arg1 % arg2 % ... % argN ; 注意这里没有示例对象,format-string代表需要格式化的字符串,后面用重载过的%跟参数 1.format占位符的使用 (占位符 是 从 1 开始的,不是从 0 开始的) std::cout<<boost::format("%1% \n %2% \n %3%" )%"first"%"second"%"third"; 上面例子中%X%表示占位符,%1%就是第一个占位符,%2%就是第二个,后面类推, 再后面的%"xxx"就对应着每个占位符,也就是说如果我们写成: std::cout<<boost::format("%2% \n %1% \n %3%" )%"first"%"second"%"third"; 将会输出 second first third 当然我们也可以分开写,比如: boost::format fmt("%2% \n %1% \n %3%" ); fmt %"first"; fmt %"second"; fmt %"third"; 2.format的C语言形式 你可以这样通过变量格式化,这与int a=5;printf("%d",a);是一个道理,不同的是format是对字符的格式化而不包含输出。 int a=5; int b=6; std::cout<< boost::format("%1% %2%" )%a%b;// 方式一 cout << boost::format("%s") % "输出内容" << endl; // 方式二 std::string s; s = str( boost::format("%s") % "输出内容" ); cout << s << endl; // 方式三 boost::format formater("%s"); formater % "输出内容"; std::string s = formater.str(); cout << s << endl; // 方式四 cout << boost::format("%1%") % boost::io::group(hex, showbase, 40) << endl;
/* 三、boost::format新的格式说明符 %{nt} 当n是正数时,插入n个绝对制表符 cout << boost::format("[t]") << endl; %{nTX} 使用X做为填充字符代替当前流的填充字符(一般缺省是一个空格) cout << boost::format("[T*]") << endl; */ cout<
#include#include #include #include #include
// 可以延迟使用,顺序不必一致 boost::format fmter("%2% %1%"); fmter % 36; fmter % 77; cout << fmter << endl; // 输出:77 36 // 可重用 fmter % 12; fmter % 24; cout << fmter << endl; // 输出:24 12 // 可直接转成字符串 std::string s = fmter.str(); std::string s2 = str( boost::format("%2% %1% %2% %1%")%"World"%"Hello"); cout << s << endl << s2 << endl; // 输出: // 24 12 // Hello World Hello World // 可以使用printf指示符 cout << boost::format("%3.1f - %.2f%%") % 10.0 % 12.5 << endl; // 输出:10.0 - 12.50% // printf指示符里使用N$指定使用第几个参数 cout << boost::format("%2$3.1f - %1$.2f%%") % 10.0 % 12.5 << endl; // 输出:12.5 - 10.00%
std::cout << boost::format("%s:%04d%02d%02d") % "日期"% 2013 % 9 % 28 << std::endl; std::string test("string"); std::cout << boost::format("%s") % test<< std::endl; boost::format fmt1("%1% + %2%*%1% = %3%"); fmt1 % 2 % 3 % (2+2*3) ; std::cout << fmt1.str() << std::endl; cout << boost::format( "%1% %2%" ) % "Hell" % "Low" << endl; string s1 = boost::str( boost::format( "%2% %1%" ) % "Hell" % "Low" ); cout << s1 << endl; wcout << boost::wformat( L"%s %X" ) % L"-1 is" % -1 << endl; wstring s2 = boost::str( boost::wformat( L"%2$s %1$.2f" ) % 3.141592 % L"Version" ); wcout << s2 << endl; char text[]="hello"; bool is_all_lower = boost::algorithm::all(text, boost::algorithm::is_lower()); char output[128]; sprintf(output, "<%s> %s in the lower case", text, (is_all_lower? "is": "is not")); cout<
在字符串处理中少不了格式化字符串,C++中传统的格式化函数是C语言的sprintf,但它一个很大的问题就是不安全。因此,在stl中引入了stringstream来实现安全格式化,但是stringstream却远不如sprintf来得直观。例如,对如如下代码:
char text[]="hello"; bool is_all_lower = boost::algorithm::all(text, is_lower()); char output[128]; sprintf(output, "<%s> %s in the lower case", text, (is_all_lower? "is": "is not"));如果把最后两句format的函数用stringstream来写的话,可读性是远不如sprintf的。
stringstream output;output << "<" << text << "> "<< (is_all_lower)? "is": "is not")<< " in the lower case";boost引入了一个提供类似.net中的string.format的方式提供格式化字符串的函数,用它来格式化的话就是如下形式:
boost::format fmt = boost::format("<%s> %s in the lower case") % text % (is_all_lower? "is": "is not");string output = fmt.str();
前面的例子中演示的是C风格的格式化字符串,boost.format也提供了类似.net风格的格式化字符串方式:
boost::format fmt = boost::format("<%1%>%2% in the lower case") % text % (is_all_lower?"is": "is not"); cout << fmt << endl;
这种方式更容易看到参数在格式化字符串中的位置,推荐这种形式。不过它的起始坐标是1而不是0,用惯了.net的string.format的朋友需要注意下。
格式化语法为: [ N$ ] [ flags ] [ width ] [ . precision ] type-char。也提供了C语言和.net两种风格。
//传统c语言风格 cout << boost::format("\n\n%s" "%1t 十进制 = [%d]\n" "%1t 格式化的十进制 = [%5d]\n" "%1t 格式化十进制,前补'0' = [%05d]\n" "%1t 十六进制 = [%x]\n" "%1t 八进制 = [%o]\n" "%1t 浮点 = [%f]\n" "%1t 格式化的浮点 = [%3.3f]\n" "%1t 科学计数 = [%e]\n" ) % "example :\n" % 15 % 15 % 15 % 15 % 15 % 15.01 % 15.01 % 15.01 << endl; //.net的风格 cout << boost::format("%1%" "%1t 十进制 = [%2$d]\n" "%1t 格式化的十进制 = [%2$5d]\n" "%1t 格式化十进制,前补'0' = [%2$05d]\n" "%1t 十六进制 = [%2$x]\n" "%1t 八进制 = [%2$o]\n" "%1t 浮点 = [%3$f]\n" "%1t 格式化的浮点 = [%3$3.3f]\n" "%1t 科学计数 = [%3$e]\n" ) % "example :\n" % 15 % 15.01 << endl;
既然boost.format函数是用来代替sprintf的,那么自然就得有异常处理的功能,而不是像sprintf那样死给你看。boost.format的处理方法是抛异常,它在如下两种情况家会抛异常:
如下代码演示了这两种情形:
try { boost::format("<%3"); } catch(std::exception& err) { cout << err.what() << endl; } boost::format fmt = boost::format("<%3%> %2% in the lower case") % text % (is_all_lower? "is": "is not"); try { cout << fmt << endl; } catch(std::exception& err) { cout << err.what() << endl; }
boost.format是以一个对象,而不是函数来实现的,导致其使用和异常处理起来要麻烦不少,不过,利用c++11的可变参数模板的语法还是可以很容易把它封装成一个可变参数的函数的形式:
string string_fromat(constchar*format, …)
需要定义三个重载版本:
template<classTFirst> void string_format(boost::format&fmt, TFirst&& first) { fmt % first; } template<classTFirst,class... TOther> void string_format(boost::format&fmt, TFirst&& first,TOther&&... other) { fmt % first; string_format(fmt, other...); } template<classTFirst,class... TOther> string string_format(constchar*format, TFirst&& first,TOther&&... other) { boost::format fmt(format); string_format(fmt, first,other...); return fmt.str(); }
现在就可以这么用了:
auto output = string_format("<%1%> %2% in the lower case", text, (is_all_lower? "is":"is not"));
所有的异常也都会在该函数中抛出,虽然效率上相对低点,但用起来要舒服点。
转载地址:http://eyzza.baihongyu.com/