2009年3月26日星期四

【原】Boost库之format的使用

Boost库的format提供了类似于C标准库函数printf的格式化字符串功能,并且它是强类型安全的。由于format重载了%操作符,因此,通过单次或多次调用%操作符可以非常方便地格式化字符串。
format的基本语法结构为:format(需要格式化的字符串 ) %参数1 %参数2 …%参数n。下面介绍format的几种使用方法。
1. 直接使用format
cout << format("%2% and %1% and %2%")%16 %"hello" << endl;
其中%1%表示第一个参数,%2%表示第二个参数,其他依此类推。另外,参数是可以复用的。

2. 使用format的str函数
format fmt("%2% and %1%")%16 %"hello";
string s = fmt.str();
cout << s << endl;

3. 使用全局的str函数
format fmt("%2% and %1%")%16 %"hello";
string s = str(fmt) ;
cout << s << endl;

4. 多次调用%操作符
format fmt("%2% and %1%");
fmt %16;
fmt %"hello";
cout << fmt << endl;

5.使用printf风格
cout << format("%d and %s")%16 %"hello" << endl;

6. 使用混合风格
cout << format("%2$s and %1$d")%16 %"hello" << endl;
其中%后面是参数的序号,$后面是printf风格的格式符。

另外,format还提供了一些其他的格式说明符。比如:%nt用于产生一个固定在第n列的\t;%nTx可以将x作为填充字符以代替当前流的填充字符(默认是一个空格)。当实际传入的参数个数与格式化字符串中需要的参数个数不一致时,format会抛出异常。举例如下:
cout << format("[abc%10t]") << format("[%10T*]") << endl;
try
{
cout << format("%1% and %2%") %16 << endl;
}
catch (exception &e)
{
cout << e.what() << endl;
}

最后谈一下使用format时需要注意的两点。一是使用默认的format风格(如%1%)输出浮点数类型时,只是将浮点数转换为对应的字符串,无法保证精度,如果需要保证精度,可以使用printf风格(如%f)输出浮点数类型;二是format不支持直接使用CString作为参数,需要先将CString转换为字符指针(如format("%1% ") %(LPCTSTR)szText)。

3 条评论:

  1. 当时看到这个类的时候的确让我兴奋了好一阵子。STL的string没有格式化字符串的方法,这下终于给boost弥补上了。而且还封装的so powerful,不过第一种和第六种方法我们平时可能会用的多一点。其实Java的printf也有类似的思想,和format第六种混合风格的语法如出一辙,呵呵。

    回复删除
  2. 嗯,介绍的非常详细,学习了。cout << format("%2% and %1% and %2%")%16 %"hello" << endl; 这一行代码输出的结果是“hello and 16 and hello”吧。另外%n%并没有带格式说明符,那我如果传入不同类型的实参值,boost如何处理呢?像前面代码如果改成cout << format("%2% and %1% and %2%")%16.00 %"hello" << endl; 输出会不会和前者不一样呢?

    回复删除
  3. 看正文最后一段,是我和hujian讨论过的一个问题...

    回复删除