发布时间:2024-05-06 13:01
在字符串处理中少不了格式化字符串,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, …)
需要定义三个重载版本:
templatevoid string_format(boost::format& fmt, TFirst&& first) { fmt % first; } template void string_format(boost::format& fmt, TFirst&& first, TOther&&... other) { fmt % first; string_format(fmt, other...); } template 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\"));
所有的异常也都会在该函数中抛出,虽然效率上相对低点,但用起来要舒服点。
到此这篇关于boost字符串处理函数format的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
[开发杂谈记录] Windows CMD使用socket代理
【TypeScript基础】TypeScript之常用类型(上)
使用vite构建一个自己的vue3.0的UI组件库,并发布到npm
IDL处理葵花8Himawari-8标准HSD数据——制作大气校正数据集(卫星角度数据)
Vue+Echarts监控大屏实例七:智慧养老监控模板实例下
android7新特性之 support library 25.0.0
基于Selenium与Pytest框架的Web UI自动化测试系统的设计与实现
web应用F12查看报错(前后端bug判断、2XX/3XX/4XX/5XX常见状态码解析)
“操作系统的「冷板凳」要坐多久?”万字长文解读16年开源人的坚持
zookeeper dubbo php,ZooKeeper分布式专题与Dubbo微服务入门 (完整版)