boost的字符串处理函数——format

来源:http://www.cnblogs.com/TianFang/archive/2013/02/04/2891501.html

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<<boost::format("[%5t] Test %5t* ");
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <boost/format.hpp>
#include <iomanip>
using namespace boost;
using namespace std;
using boost::io::group;
/*format类摘要
namespace boost {

template<class charT, class Traits=std::char_traits<charT> >
class basic_format
{
public:
  typedef std::basic_string<charT, Traits> string_t;
  typedef typename string_t::size_type     size_type;
  basic_format(const charT* str);
  basic_format(const charT* str, const std::locale & loc);
  basic_format(const string_t& s);
  basic_format(const string_t& s, const std::locale & loc);
  basic_format& operator= (const basic_format& x);

  void clear(); // reset buffers
  basic_format& parse(const string_t&); // clears and parse a new format string

  string_t str() const;
  size_type size() const;

  // pass arguments through those operators :
  template<class T>  basic_format&   operator%(T& x);
  template<class T>  basic_format&   operator%(const T& x);

  // dump buffers to ostream :
  friend std::basic_ostream<charT, Traits>&
  operator<< <> ( std::basic_ostream<charT, Traits>& , basic_format& ); 

   // Choosing which errors will throw exceptions :
   unsigned char exceptions() const;
   unsigned char exceptions(unsigned char newexcept);

// ............  this is just an extract .......
}; // basic_format

typedef basic_format<char >          format;
typedef basic_format<wchar_t >      wformat;

// free function for ease of use :
template<class charT, class Traits>
std::basic_string<charT,Traits>  str(const basic_format<charT,Traits>& f) {
      return f.str();
}

} // namespace boost

*/
/*格式化语法:
 * 1.%05d:输出宽度为5的整数,不足位用0填充
 * 2.%-8.3f:输出左对齐,总宽度为8,小数位3位的浮点数
 * 3.%10s:输出10位的字符串,不足位用空格填充
 * 4.%05x:输出宽度为5的大写16进制数,不足位用0填充
 * 5.%|spec|:与printf格式选项功能相同,但两边增加了竖线分隔,可以更好地区分格式化选项与普通字符
 * 6.%N%:标记第N个参数,相当于占位符,不带任何奇特的格式化选项
 *
 * 建议:
 * 1.format由于要做安全检查工作,性能略差,约比printf慢2到5倍,为了提高format的性能,建议在编程中应该先建立const format对象,然后拷贝这个对象进行格式化操作
 *
 * 高级功能:
 * 1.basic_format& bind_arg(int argN,const T& val); //将第argN个参数绑定为val,即使调用clear()也保持不变
 * 2.basic_format& clear_bind(int argN);    //取消格式化字符串第argN位置的参数绑定
 * 3.basic_format& clear_binds();   //取消格式化字符串所有位置参数绑定,并调用argN
 * 4.basic_format& modify_item(int itemN,T manipulator);    //设置格式化字符串第itemN位置的格式化选项,manipulator是一个boost::io::group返回的对象
 * */
int main( int argc,char **argv)
{
    cout << format("%s:%d+%d=%d\n")%"sum"% 1%2%(1+2); //经典用法
    cout << format("%1% %2%") % 36 %37; //简单风格,可以重新排列输出
    cout << format("(x,y)=(%1$+5d,%2$+5d)\n") %-23 %35;    //精确的格式化,带posix_printf位置提示符
    format fmt("(%1%+%2%)*%2%=%3%");
    fmt % 2 % 5;
    fmt % ((2+5*5));

    format fmt1("%05d\n%-8.3f\n%10s\n%05x\n");
    cout << fmt1 %62 %2.236 %" 12345678" %48;
    cout << fmt.str() << endl;

    format fmt2("%1% %2% %3% %2% %1%\n");
    cout << fmt2 %1 %2 %3;
    fmt2.bind_arg(2,10);
    cout << fmt2 %1 %3;

    fmt2.clear();
    cout << fmt2 % group(showbase,oct,111) % 333;
    fmt2.clear_binds();

    fmt2.modify_item(1,group(hex,right,showbase,setw(8),setfill('*')));
    cout << fmt2 %49 %20 %100;
     return (0);
}
// 可以延迟使用,顺序不必一致
    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<<output<<endl;

用boost::format来格式化字符串

在字符串处理中少不了格式化字符串,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的处理方法是抛异常,它在如下两种情况家会抛异常:

  1. format字符串非法
  2. 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"));

所有的异常也都会在该函数中抛出,虽然效率上相对低点,但用起来要舒服点。

时间: 2024-09-21 17:59:16

boost的字符串处理函数——format的相关文章

PHP开发中常用的字符串操作函数

1,拼接字符串 拼接字符串是最常用到的字符串操作之一,在PHP中支持三种方式对字符串进行拼接操作,分别是圆点.分隔符{}操作,还有圆点等号.=来进行操作,圆点等号可以把一个比较长的字符串分解为几行进行定义,这样做是比较有好处的. 2,替换字符串 在PHP这门语言中,提供了一个名字叫做substr_replace()的函数,该函数的作用可以快速的完成扫描和编辑文本内容较多的字符串替换功能.他的语法格式: mixed substr_replace(mixed $string,string $repl

php字符串处理函数库

函数|字符串 php字符串处理函数库 AddSlashes 字符串加入斜线. 语法: string addslashes(string str); 返回值: 字符串 函数种类: 资料处理 本函数使需要让数据库处理的字符串,引号的部份加上斜线,以供数据库查询 (query) 能顺利运作.这些会被改的字符包括单引号 (').双引号 (").反斜线 backslash (\) 以及空字符 NUL (the null byte). bin2hex 二进位转成十六进位. 语法: string bin2he

Mysql字符串处理函数详细介绍、总结

 这篇文章主要介绍了Mysql字符串处理函数详细介绍.总结,需要的朋友可以参考下 一.简明总结 ASCII(char) 返回字符的ASCII码值 BIT_LENGTH(str) 返回字符串的比特长度 CONCAT(s1,s2-,sn)  将s1,s2-,sn连接成字符串 CONCAT_WS(sep,s1,s2-,sn) 将s1,s2-,sn连接成字符串,并用sep字符间隔 INSERT(str,x,y,instr) 将字符串str从第x位置开始,y个字符长的子串替换为字符串instr,返回结果

Linux下常用C语言字符串操作函数

stroul, strdup snprintf() atio   C中常用字符串操作函数 #include <string.h>   size_t strlen(const char *s)   测量字符串长度s的实际长度. 例如s[20]="abc",那么strlen(s)的结果是3,而不是20.这就是实际长度   char *strcat(const char *s1, const *s2)    将字符串s2连接到s1的尾部.从s1的/0开始.   int strcm

PHP常用字符串操作函数实例总结(trim、nl2br、addcslashes、uudecode、md5等)_php技巧

本文实例总结了PHP常用字符串操作函数.分享给大家供大家参考,具体如下: /*常用的字符串输出函数 * * echo() 输出字符串 * print() 输出一个或多个字符串 * die() 输出一条信息,并退出当前脚本 * printf() 输出格式化字符串 * sprintf() 把格式化的字符串写入到一个变量中 * */ //ucfirst //将字符串中的首字母转换为大写 $str="string"; echo ucfirst($str); echo "<hr&

PHP开发中常用的字符串操作函数_php技巧

1,拼接字符串 拼接字符串是最常用到的字符串操作之一,在PHP中支持三种方式对字符串进行拼接操作,分别是圆点.分隔符{}操作,还有圆点等号.=来进行操作,圆点等号可以把一个比较长的字符串分解为几行进行定义,这样做是比较有好处的. 2,替换字符串 在PHP这门语言中,提供了一个名字叫做substr_replace()的函数,该函数的作用可以快速的完成扫描和编辑文本内容较多的字符串替换功能.他的语法格式: mixed substr_replace(mixed $string,string $repl

php字符串操作函数入门篇

php教程字符串操作函数入门篇 1.字符串的定义与显示 定义:通过"",''来标志 显示:echo()和print(),但print()具有返回值值,1,而echo()没有,但echo比print()要快,print()能用在复合语句中. 2.字符串的格式化 printf(string $format[,mixed$args]) 第一参数是格式字符串,$args是要替换进来的值,prinf("%d",$num); 说明,如果想打印一个"%",必须

mysql常用日期 字符串处理函数命令

函数如下: left,right  字符串截取 from_unixtime  格式化unix时间戳 concat  字符串连接函数 max  取某列最大值 min 取某列最小值 sum 计算某列的和 count 统计条数 md5 返回md5加密码的串 format 格式化数字为xx,xxx,xxx.xxxx格式 比如1,1000.123 length   计算某个字符串长度 distinct  去重复 replace  替换字符串 in 指定查询某个值的记录 like  模糊查询 is null

C++的字符串分割函数的使用详解_C 语言

经常碰到字符串分割的问题,这里总结下,也方便我以后使用. 一.用strtok函数进行字符串分割 原型: char *strtok(char *str, const char *delim); 功能:分解字符串为一组字符串. 参数说明:str为要分解的字符串,delim为分隔符字符串. 返回值:从str开头开始的一个个被分割的串.当没有被分割的串时则返回NULL. 其它:strtok函数线程不安全,可以使用strtok_r替代. 示例: //借助strtok实现split #include <st