一起学习Boost标准库--Boost.texical_cast&format库

今天接续介绍有关字符串表示相关的两个boost库:

  • lexical_cast 将数值转换成字符串
  • format 字符串输出格式化

首先,介绍下lexical_cast ,闻其名,知其意。类似C中的atoi 函数,可以进行字符串与整数/浮点数之间的字面转换

Boost::lexical_cast库

前期准备

lexical_cast库位于boost命名空间下,使用需要引入头文件

#include <boost/lexical_cast.hpp>
using namespace boost;

函数声明

lexical_cast使用类似C++标类型操作符的形式进行通用的语法,其声明如下:

// 1. 标准形式,转换数字和字符串
template <typename Target, typename Source>
inline Target lexical_cast(const Source &arg);

// 2. 转换C字符串
template <typename Target>
inline Target lexical_cast(const char* chars, std::size_t count);
inline Target lexical_cast(const unsigned char* chars, std::size_t count);
inline Target lexical_cast(const signed char* chars, std::size_t count);
inline Target lexical_cast(const wchar_t* chars, std::size_t count);
inline Target lexical_cast(const char16_t* chars, std::size_t count);
inline Target lexical_cast(const char32_t* chars, std::size_t count);
  • 第一种形式有两个模版参数,Target 为需要转换的目标类型,通常是数字类型或者std::string,第二个参数Source 则不用写,可以通过函数参数推到出来,调用形式如下
lexical_cast<int>("123");
lexical_cast<double>("234.123");
lexical_cast<std::string>(567.789);
  • 第二种形式主要用来处理C字符串,支持多种类型,只接受一个模板参数Target,指明转换后的目标类型,函数参数charscount 则标记了要转换的字符串范围
const char* double_str = "123.456";
double d1 = lexical_cast<double>(double_str, strlen(double_str));

使用样例

通过上文的介绍,您大概已经知道如何使用了,此处,我们就通过一个简单Demo来使用lexical_cast库

#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
using namespace boost;

int main()
{
    int age = lexical_cast<int>("29");
    int money = lexical_cast<long>("10000000");
    float pai_f = lexical_cast<float>("3.1415926535");
    double pai_d = lexical_cast<double>("3.14159265358979323846264338324990", 20);

    cout << "age: " << age << endl
        << "money: " << money << endl
        << setiosflags(ios::fixed)
        << "pai_f: " << setprecision(8) << pai_f << endl
        << "pai_d: " << setprecision(16) << pai_d << endl;

    cout << lexical_cast<string>(age) << endl
        << lexical_cast<string>(money) << endl
        << lexical_cast<string>(pai_d) << endl;

    return 0;
}

Output:

age: 29
money: 10000000
pai_f: 3.14159274
pai_d: 3.1415926535897931
29
10000000
3.1415926535897931

注意: 使用lexical_cast时要注意,转换成数字的字符串中只能有数字和小数点,不能出现字母或其他非数字字符,同时也不支持高级的格式控制,如果要进行复杂的格式控制可以使用std::stringstramboost::format (后面介绍该库)

错误处理

当lexcial_cast无法执行转换操作的时候会抛出异常bad_lexical_cast ,他是std::bad_cast 的派生类,此处以上文中注意 来说明

    try
    {
        int age = lexical_cast<int>("0x64");
        //int age = lexical_cast<int>("100L");
        //bool f = lexical_cast<bool>("false");
        cout << "age: " << age << endl;
    }
    catch (bad_lexical_cast &e)
    {
        cout << "cast error: " << e.what() << endl;
    }

Output:

cast error: bad lexical cast: source type value could not be interpreted as target

如果每次都通过异常捕获来处理,就比较麻烦了,还好lexical_cast为我们想到了,再命名空间boost::conversion 提供方法try_lexical_convert() 函数来避免抛出异常,通过返回bool值来表示是否转换成功。具体使用如下:

using namespace boost::conversion;
int x = 0;
if (!try_lexical_convert<int>("0x64", x))
    cout << "convert failed" << endl;
else
    cout << "x: " << x << endl;

Boost.format库

C++标准库提供了强大的输入输出流处理,可以通过设置输出各种各样的格式,精度控制、填充、对齐等。但是唯一缺点就是太复杂了,真心记不住这么多,还是怀恋printf() 可以通过规定的样式输出想要的格式。虽然C++中可以继续使用printf() 但它缺乏类型安全检查等其他缺点,重点就是boost.format库实现了类似于printf() 的格式化对象,可以把参数格式化到一个字符串,而且是类型安全的,是一个header-only 的函数库,只要准备好头文件,不用预先编译就可以使用了,最主要的是用着还挺顺手。

前期准备

format库位于boost命名空间中,需引入头文件:

#include <boost/format.hpp>
using namespace boost;

类声明

template <class Ch,
        class Tr = BOOST_IO_STD char_traits<Ch>, class Alloc = std::allocator<Ch> >
    class basic_format;

typedef basic_format<char >     format;

template<class Ch, class Tr, class Alloc>
class basic_format
{
public:
    explicit basic_format(const Ch* str = NULL);
    explicit basic_format(const string_type& s);
    basic_format(const basic_format& x);
    basic_format& operator= (const basic_format& x);

    basic_format& clear();       // 清空缓存
    basic_format& parse(const string_type&); // 重新格式化

    size_type   size() const;    // 获取字符串长度
    string_type str()  const;    // 获取格式化后的字符串

    template<class T>
    basic_format&   operator%(const T& x); //重载操作符%

    template<class Ch2, class Tr2, class Alloc2>
    friend std::basic_ostream<Ch2, Tr2> &
        operator<<(std::basic_ostream<Ch2, Tr2> &,
        const basic_format<Ch2, Tr2, Alloc2>&); //流输出
}; // class basic_format
  • str: 返回format对象内部已经格式化号的字符串
  • size : 返回format对象格式化号的字符串长度,可以直接从str()返回的string.size()
  • parse :重新格式化,清空format对象内部缓存,改用一个新的格式化字符串,如果只是想清空缓存,则使用clear(),它把format对象恢复到初始化状态
  • operator% : 可以接受待格式化的任意参数,%输入的参数个数必须等于格式化字符串中要求的个数,过多或者过少都会抛出异常
  • operator<<:重载流输入操作符,可以直接输出格式化好的字符串

不过要注意的是,透过operator%传给boost::format对象的变量是会储存在对象内部的,所以可以分批的传入变数;但是如果变量的数量不符合的话,在编译阶段虽然不会出现错误,可是到了执行阶段还是会让程序崩溃,所以在使用上必须小心一点。 不过,在有输出后,是可以再重新传入新的变量、重复使用同一个boost::format 对象的。

格式化语法

format基本继承了printf的格式化语法,格式化选项以%开始,后面是格式规则

%[标志][输出最少宽度][.精度][长度]类型

详细请参考printf格式输出

除了支持printf格式化外,还新增了格式:

  • %|spec| :与printf格式选项功能相同,但是两边增加竖线分隔,更好的区分格式化选项与普通字符
  • %N% :标记第N个参数,相当于占位符,不带任何其他格式化的选项

通过以下使用竖线分隔,更加清楚明了格式化参数

format fmt("%05d\n%-8.3f\n% 10s\n%05X\n");
format fmt("%|05d|\n%|-8.3f|\n%| 10s|\n%|05X|\n");

使用样例

#include <boost/format.hpp>
#include <iostream>
using namespace std;
using namespace boost;

int main()
{
    cout << "-------------"<<endl;
    format fmt("%d + %d = %d");
    fmt % 2 % 3 % 5;
    cout << fmt.str() << endl;

    cout << "-------------"<<endl;
    format fmt2("%05d\n%-8.3f\n% 10s\n%05X\n");
    fmt2 % 123;
    fmt2 % 456.7;
    fmt2 %"boost" % 100;
    cout << fmt2 << endl;

    cout << "-------------"<<endl;
    cout << boost::format("x=%1%,  y=%2% ,z= %3%") % "format" % 40.2 % 134 << endl;
    cout << "-------------"<<endl;
    return 0;
}

Output:

-------------
2 + 3 = 5
-------------
00123
456.700
     boost
00064

-------------
x=format,  y=40.2 ,z= 134
-------------

原文地址:https://www.cnblogs.com/wqliceman/p/9033606.html

时间: 2024-11-05 16:08:59

一起学习Boost标准库--Boost.texical_cast&format库的相关文章

一起学习Boost标准库--Boost.StringAlgorithms库

概述 在未使用Boost库时,使用STL的std::string处理一些字符串时,总是不顺手,特别是当用了C#/Python等语言后trim/split总要封装一个方法来处理.如果没有形成自己的common代码库,那就悲剧了,每用一次都要写一次,虽然难度不大,但是每次重复这样工作也还是比较费劲.一般通过STL进行封装如下: // trim from start inline std::string &LeftTrim(string &s) { s.erase(s.begin(), std:

boost标准库开发环境搭建

1.下载boost相关的库的安装包 网址:http://www.boost.org/ 其中1.55.0版本的下载地址是:http://sourceforge.net/projects/boost/files/boost/1.55.0/ 截图: 2.boost开发相关的软件: boost_1_55_0.tar.gz  Linux平台下面的boost源码包 boost_1_55_0.zip    Windows平台下面的boost源码包 boost_1_55_0-bin-msvc-all-32-64

C++ 三大库boost、loki、stlport

C++ 三大库boost.loki.stlport 在C++中,库的地位是非常高的.C++之父 Bjarne Stroustrup先生多次表示了设计库来扩充功能要好过设计更多的语法的言论.现实中,C++的库门类繁多,解决的问题也是极其广泛,库从轻量级到重 量级的都有.不少都是让人眼界大开,亦或是望而生叹的思维杰作.由于库的数量非常庞大,而且限于笔者水平,其中很多并不了解.所以文中所提的一些库都是比较著名的大型库. 标准库 标准库中提供了C++程序的基本设施.虽然C++标准库随着C++标准折腾了许

【转】值得学习的C语言开源项目和库

- 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在压力下工作的性能,最多可以模拟3万个并发连接去测试网站的负载能力.Webbench使用C语言编写, 代码实在太简洁,源码加起来不到600行. 下载链接:http://home.tiscali.cz/~cz210552/webbench.html - 2. Tinyhttpd tinyhttpd是一个超轻量型Http Server,使用C

《C Primer Plus》学习笔记——C预处理器和C库

1.在Unix系统中,尖括号告诉预处理器在一个或多个标准系统目录中寻找文件.双引号告诉预处理器先在当前目录(或文件名中指定的其他目录)中寻找文件,然后在标准位置寻找文件. 2.#undef指令:取消定义一个给定的#define #define LIMIT 400 #undef LIMIT 3.条件编译 #ifdef.#else和#endif指令 #ifdef 宏名 //语句段1 #else //语句段2 #endif 作用:当标识符已经被定义过(一般是用#define命令定义),则对语句段1进行

以boost::function和boost:bind取代虚函数

转自:http://blog.csdn.net/Solstice/archive/2008/10/13/3066268.aspx 这是一篇比较情绪化的blog,中心思想是"继承就像一条贼船,上去就下不来了",而借助boost::function和boost::bind,大多数情况下,你都不用上贼船. boost::function和boost::bind已经纳入了std::tr1,这或许是C++0x最值得期待的功能,它将彻底改变C++库的设计方式,以及应用程序的编写方式. Scott

boost::string or boost::regex

有时候写代码时会遇到下面问题 如果有一个文本文件,其包括内容类似于C语言,当中有一行例如以下格式的语句: layout (local_size_x = a,local_size_y = b, local_size_z = c) in; 当中用蓝色标记出的部分(layout, local_size_x, local_size_y, local_size_z, in)为keyword,斜体字部分(a, b, c)为数据类型为unsigned int的数字,请编写一个函数,用于从文件里抽取出a, b,

Linux学习之标准IO 管道 033_7

默认输入为键盘,标准输出为显示器,错误输出为显示器 把标准输出和错误输出重定向到文件: command operator filename operators: >:标准输出重定向 :把ls -R的输出重定向到文件 2>:错误输出重定向 &>:将正确和错误的输出都重定向 同时将正确和错误信息分别导入到不同文件: 以上默认覆盖,如果在文件末尾添加则用>>s 把错误输出重定向到空设备,也就是忽略错误信息 管道: 将前面一条命令执行的结果作为后面一条命令的输入 如: ls

STM32标准外设库、 HAL库、LL库

工作以来一直使用ST的STM32系列芯片,ST为开发者提供了非常方便的开发库.到目前为止,有标准外设库(STD库).HAL库.LL库 三种.前两者都是常用的库,后面的LL库是ST最近才添加,目前支持的芯片也偏少.各库如下所示: 其中STD库和HAL库两者相互独立,互不兼容.几种库的比较如下: 目前几种库对不同芯片的支持情况如下: 上图中,LL库目前有部分芯片不支持,官方计划2017年逐步完善. STM32Snippets 它是代码示例的集合,直接基于STM32外设寄存器,可在文档和软件包中使用.