用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(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相关推荐

  1. python format函数实例_Python字符串格式化,format格式化函数详细使用

    Python接触比较多的是字符串,那么操作字符串也就多.Python 支持格式化字符串的输出 . 尽管这样可能会用到非常复杂的表达式,但最基本的用法是将一个值插入到一个有字符串格式符的字符串中. 代码 ...

  2. C语言sprintf函数(发送格式化输出到 str 所指向的字符串)(format 标签属性)(字符串拼接)(数字转字符串、浮点数转字符串)

    C语言函数 snprintf()(发送有限字符格式化输出到 str 所指向的字符串)(字符串拼接) 文章目录 描述 声明 参数 返回值 实例 20220124 上面的实例太简陋了,我们拓展一下 实例1 ...

  3. python中upper函数有什么用_几个有用的python字符串函数(format,join,split,startwith,endwith,lower,upper)...

    你需要知道的python字符串函数 format 字符串的format函数为非字符串对象嵌入字符串提供了一种非常强大的方法.在format方法中,字符串使用{}来代替一系列字符串的参数并规定格式.下面 ...

  4. Python字符串类型:字符串索引、字符串切片、字符串format()方法格式化、字符串操作符、字符串处理函数

    字符串:由0个或多个字符组成的有序序列sequence. 一.字符串表示方式:2类4种 由一对单引号或双引号表示,该方式仅用于表示单行字符串 由一对三单引号或三双引号,该方式可以表示多行字符串 如果希 ...

  5. Python 基础之字符串操作,函数及格式化format

    一.字符串的相关操作 1.字符串的拼接 + strvar1 = "我爱你," strvar2 = "亲爱的姑凉" res = strvar1 + strvar2 ...

  6. boost之字符串--lexical_cast

    函数由来 顾名思义,lexical_cast库进行"字面值"的转换,类似c中的atoi()函数,可以进行字符串与整数/浮点数之间的字面转换. #include<boost/l ...

  7. boost I 字符串与文本处理

    目录 一.lexical_cast 与C语言.C++的对比 二.format 1.format类 2.格式化语法 三.string_ref 1.背景 2.boost::string_ref 3.rem ...

  8. python字符串find函数-Python字符串的方法,查找和替换

    Python数字 整型 int 如:1 4 8 浮点型 float 如:1.0 3.6 78.9 长整型 long 如:1L 37565846588L(在一个整数后面加上L就是长整型,理论上长整型的长 ...

  9. mysql的字符串处理函数

    一.简明总结 ASCII(char) 返回字符的ASCII码值 BIT_LENGTH(str) 返回字符串的比特长度 CONCAT(s1,s2-,sn) 将s1,s2-,sn连接成字符串 CONCAT ...

最新文章

  1. 阿里OceanBase GitHub点赞送礼引争议,CTO道歉,贾扬清、李沐讨论开源刷Star
  2. WINDOWSPHONE STUDY1:创建一个 Windows Phone 7 下的简单 RSS 阅读器
  3. 框架:AspectJ
  4. JavaScript中的 apply 与 call 方法
  5. php判断平年和闰年,平年和闰年的三种判断方法
  6. 鸿蒙系统和中标麒麟系统关系,操作系统有哪些 先有鸿蒙后有麒麟V10 为5G时代量身定做...
  7. 刚看了一个视频,介绍了实体店十几种线上线下引流方法
  8. 51nod-1246:罐子和硬币
  9. Android APP 设计说明书模板
  10. 浏览器下载大文件时下载完成但大小对不上
  11. 【CCNA第二天】路由器密码破解及恢复
  12. 新增修改BP客户/供应商
  13. WIN7共享WIFI上网
  14. GrapeCity Documents for PDF[GcPDF]
  15. Elasticsearch教程(31) es mapping参数doc_values enabled ignore_above norms store详解
  16. unity 打安卓包 华为手机图片被压扁
  17. Node.js 字体格式转换 ttf2eot ttf2woff ttf2svg
  18. L415 Fat Is Not the Problem—Fat Stigma Is
  19. 软件工程头歌人机交互部分设计用例
  20. MSXML2.ServerXMLHTTP

热门文章

  1. r语言 调用c windows,R:window()函数
  2. 2022/4/3刷题
  3. FPGA之道(5)MOS管简介
  4. Wallace树专题研究
  5. 「镁客·请讲」深睿医疗乔昕:AI医疗才起步,说变革尚早
  6. jenkins需安装插件总结
  7. Web性能压力测试工具——Siege详解
  8. JavaScript 正则表达式的使用
  9. CentOS 6.7安装ZooKeeper 3.4.9
  10. memcached的应用和兼容程序