用boost::format来格式化字符串
来源:互联网 发布:衣服淘宝店名大全 编辑:程序博客网 时间:2024/06/06 06:54
转: 用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的处理方法是抛异常,它在如下两种情况家会抛异常:
- format字符串非法
- 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(const char* format, …)
需要定义三个重载版本:
template<class TFirst>
void string_format(boost::format& fmt, TFirst&& first)
{
fmt % first;
}
template<class TFirst, class... TOther>
void string_format(boost::format& fmt, TFirst&& first, TOther&&... other)
{
fmt % first;
string_format(fmt, other...);
}
template<class TFirst, class... TOther>
string string_format(const char* 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"));
所有的异常也都会在该函数中抛出,虽然效率上相对低点,但用起来要舒服点。
PS:可变参数模板的特性在vc 2012中还不支持,不过微软已经发布了一个CTP版本的编译器使得可以在vc 2012中使用该特性,应该在下个update版本或sp1中就会正式支持。gcc可以完美支持,windows下也可以通过MinGW使用该特性。
- 用boost::format来格式化字符串
- boost format字符串格式化
- boost::format(字符串格式化库)
- boost——format格式化字符串
- 字符串Format格式化(Delphi)
- 字符串格式化(format)
- RMAN FORMAT字符串格式化
- Format格式化字符串
- python format格式化字符串
- String format 格式化字符串
- 格式化format()输出字符串
- python.format() 格式化字符串
- String.format(格式化字符串)
- String.format() 格式化字符串
- Python格式化字符串format
- String.format() 格式化字符串
- 字符串格式化-format()
- python:格式化字符串,format
- 14.5.3 Locks Set by Different SQL Statements in InnoDB
- Deep Learning Papers Reading Roadmap
- 浅析C++程序栈
- 分类算法:kNN
- Tesseract-OCR 字符识别---样本训练 [转]
- 用boost::format来格式化字符串
- 使用nc传输数据
- Apache CXF拦截器Interceptor实现WebServices用户验证
- Android Studio开发常见异常(合辑)
- 企业级Docker镜像仓库的管理和运维
- python版c语言经典50例---程序一
- 现已发布:Android 7.1 Developer Preview
- 位图索引bitmap(一):基本概念
- Objective-C消息发送和消息转发机制