boost字符串处理函数format的用法

 更新时间:2022年06月18日 16:04:28   作者:天方  
这篇文章介绍了boost字符串处理函数format的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

用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"));

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

到此这篇关于boost字符串处理函数format的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C++线性表深度解析之动态数组与单链表和栈及队列的实现

    C++线性表深度解析之动态数组与单链表和栈及队列的实现

    这篇文章主要为大家详细介绍了C++实现动态数组、单链表、栈、队列,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • C++ explicit关键字的使用详解

    C++ explicit关键字的使用详解

    这篇文章主要介绍了C++ explicit关键字的使用详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • C++通过自定义函数找出一个整数数组中第二大数的方法

    C++通过自定义函数找出一个整数数组中第二大数的方法

    这篇文章主要介绍了C++通过自定义函数找出一个整数数组中第二大数的方法,涉及C++针对数组的遍历操作相关技巧,需要的朋友可以参考下
    2015-06-06
  • C++性能剖析教程之循环展开

    C++性能剖析教程之循环展开

    这篇文章主要给大家介绍了关于C++性能剖析教程之循环展开的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-06-06
  • VS2019 更新MSDN并创建快捷方式的实现

    VS2019 更新MSDN并创建快捷方式的实现

    这篇文章主要介绍了VS2019 更新MSDN并创建快捷方式的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • 深入解析C++和JAVA的字符串

    深入解析C++和JAVA的字符串

    这篇文章主要介绍了C++和JAVA的字符串,JAVA 中String 和StringBuffer的区别,需要的朋友可以参考下
    2015-07-07
  • C语言教程之数组详解

    C语言教程之数组详解

    这篇文章主要为大家介绍了C语言教程之数组,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • C++存储链接性原理详解

    C++存储链接性原理详解

    这篇文章主要为大家介绍了C++存储链接性原理详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • 基于C中一个行压缩图的简单实现代码

    基于C中一个行压缩图的简单实现代码

    首先简单说一下什么是行压缩图,其实严格意义上应该是行压缩矩阵
    2013-05-05
  • 关于C++中数据16进制输出的方法

    关于C++中数据16进制输出的方法

    本文主要介绍了关于C++中数据16进制输出的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03

最新评论