浅尝boost之format

概述 

     std::string是个很不错的东东,但实际使用时基本在每个程序里都会遇到不愉快的事情:格式化字符串。我甚至由于这个原因在代码里引入平台有关的MFC,ATL等本来不需要在项目中使用的一些重量级的框架,就为了能轻松的做格式化字符串 :-) 。曾尝试过将ATL::CString的format函数提取出来使用,但ATL::CString的底层调用了windows独有函数,无法跨越平台。当然,现在有了boost::format,我们不用再担心了。boost::format重载了'%'操作符,通过多次调用'%'操作符就能将参数非常方便格式化成字符串,并实现了ATL::CString和C#中的string两者的格式化字符串功能。除了语法刚开始感觉到怪异,功能足以让人感觉到兴奋! 

 

在字符串处理中少不了格式化字符串,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的朋友需要注意下。

 

一、boost::format工作的方式 
  
 基本的语法,boost::format( format-string ) % arg1 % arg2 % ... % argN 
  
 下面的例子说明boost::format简单的工作方式  
 

// 方式一 
 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实际使用的实例 
  
 格式化语法: [ N$ ] [ flags ] [ width ] [ . precision ] type-char  
  


// ATL::CString风格 
 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; 
 
 // C#::string风格 
 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; 


输出结果 
/* 
example : 
 十进制 = [15] 
 格式化的十进制 = [ 15] 
 格式化十进制,前补'0' = [00015] 
 十六进制 = [f] 
 八进制 = [17] 
 浮点 = [15.010000] 
 格式化的浮点 = [15.010] 
 科学计数 = [1.501000e+001] 
*/


三、boost::format新的格式说明符 
  
 %{nt} 
 当n是正数时,插入n个绝对制表符 
 cout << boost::format("[%10t]")  << endl; 
  
 %{nTX} 
 使用X做为填充字符代替当前流的填充字符(一般缺省是一个空格) 
 cout << boost::format("[%10T*]")  << endl;  

四、异常处理 
 

 一般写法:

 try 
 { 
 cout << boost::format("%d%d") % 1 << endl; 
 } 
 catch(std::exception const & e) 
 { 
 cout << e.what() << endl; 
 
 // 输出内容: 
 // boost::too_few_args: format-string refered to more arguments than were passed 
 } 

 

 boost::format的文档中有选择处理异常的办法,不过个人感觉实用性可能不强,下面是文档中的例子  
  

 // boost::io::all_error_bits selects all errors 
 // boost::io::too_many_args_bit selects errors due to passing too many arguments. 
 // boost::io::too_few_args_bit selects errors due to asking for the srting result before all arguments are passed 
 
 boost::format my_fmt(const std::string & f_string) 
 { 
 using namespace boost::io; 
 format fmter(f_string); 
 fmter.exceptions( all_error_bits ^ ( too_many_args_bit | too_few_args_bit ) ); 
 return fmter; 
 } 
 cout << my_fmt(" %1% %2% \n") % 1 % 2 % 3 % 4 % 5;

 

  
五、还有其它一些功能,但暂时感觉派不上用处,就不去深究了。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值