Boost库Lexical_Cast模块使用介绍

Boost.Lexical_Cast模块提供了一种方便的通用转换方式,支持文本与各种类型间的转换,包括字符串转数值、数值转字符串以及自定义类型转换。它弥补了标准C和C++库在转换功能上的不足,如易用性、可扩展性和安全性。标准库的函数如atoi、strtol和stringstream等在处理复杂或自定义类型时不够灵活,而Lexical_Cast则提供了更强大且安全的解决方案。
摘要由CSDN通过智能技术生成

模块功能

Lexical_Cast模块提供了一种方便且一致的形式用于支持与任意类型对应的文本和其值之间的通用转换。

版本说明

本文中介绍的Lexical_Cast模块内容是基于Boost 1.56.0的。

模块用法

字符串转数值

#include <boost/lexical_cast.hpp>
#include <iostream>

using namespace std;

int main() {
  using boost::bad_lexical_cast;
  using boost::lexical_cast;
  using boost::conversion::try_lexical_convert;

  try {
    // 测试使用lexical_cast
    short s = lexical_cast<short>("123");
    cout << s << endl;

    // 测试使用try_lexical_convert
    float f;
    for (auto str : {"abc", "1.2"}) {
      if (try_lexical_convert<float>(str, f)) {
        cout << "Succes to convert \"" << str << "\" to " << f << endl;
      } else {
        cout << "Fail to convert \"" << str << "\" to float" << endl;
      }
    }

    // 测试抛出bad_lexical_cast异常
    double d = lexical_cast<double>("123abc");
    cout << d << endl;
  } catch (const bad_lexical_cast& ex) {
    cout << ex.what() << endl;
  }
}

上面代码的运行结果如下:

123
Fail to convert "abc" to float
Succes to convert "1.2" to 1.2
bad lexical cast: source type value could not be interpreted as target

数值转字符串

#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>

using namespace std;

int main() {
  using boost::bad_lexical_cast;
  using boost::lexical_cast;
  using boost::conversion::try_lexical_convert;

  //测试使用lexical_cast
  const auto s1 = lexical_cast<string>(1.532e5);
  cout << s1 << endl;
  string s2;
  int val = 123;

  //测试使用try_lexical_convert
  if (try_lexical_convert<string>(val, s2)) {
    cout << "Success to convert " << val << " to \"" << s2 << "\"" << endl;
  } else {
    cout << "Fail to convert " << val << " to string" << endl;
  }
}

上面程序的运行结果如下:

153200

自定义类转字符串

#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>

using namespace std;

class Point {
 public:
  Point(float x, float y) : x_(x), y_(y) {}
  friend ostream &operator<<(ostream &output, const Point &p) {
    output << "(" << p.x_ << ", " << p.y_ << ")";
    return output;
  }

 private:
  const float x_;
  const float y_;
};

int main() {
  using boost::bad_lexical_cast;
  using boost::lexical_cast;

  const auto s = lexical_cast<string>(Point(1.1f, 2.2f));
  cout << s << endl;
}

上面程序的运行结果如下:

(1.1, 2.2)

字符串转自定义类

class Point {
 public:
  friend istream &operator>>(istream &input, Point &p) {
    input >> p.x_;
    return input;
  }

  friend ostream &operator<<(ostream &output, const Point &p) {
    output << "Point(" << p.x_ << ")";
    return output;
  }

  Point() { x_ =0; }
  Point(const Point &pt) {
    x_ = pt.x_;
  }

 private:
  float x_;
};

int main() {
  using boost::bad_lexical_cast;
  using boost::lexical_cast;

  const auto p = lexical_cast<Point>(string("3.3"));
  cout << p << endl;
}

上面程序的运行结果如下:

Point(3.3)

为什么不使用标准库里的转换

标准C和c++库提供了许多执行此类转换的工具。但是,它们在易用性、可扩展性和安全性方面有所不同。

例如,由atoi代表的标准C函数家族有许多限制:

  • 只支持单向转换:从文本到内部数据类型。使用C库以另一种方式进行转换,要么会带来sprintf函数的不便和安全问题,要么会丧失与itoa等非标准函数相关的可移植性;
  • 支持的类型范围仅是内置数值类型的子集,即int、long和double;
  • 类型的范围不能以统一的方式扩展。例如,将字符串转换成复数(Complex)或有理数(Rational)。

以strtol为代表的标准C函数具有相同的基本限制,但对转换过程提供了更好的控制。然而,对于一般情况,这种控制通常不是不需要就是不使用。

scanf函数家族提供了更强大的控制,但也缺乏安全性和易用性。

标准c++库的stringstream对I/O与文本任意类型之间的格式和转换提供了大量的控制。然而,对于简单的转换,直接使用stringstream可能是笨拙的(引入额外的局部变量并失去了插入表达式的便捷性)或隐晦的(在表达式中创建stringstream对象作为临时对象)。

标准c++库的facet为控制文本表示提供了全面的概念和工具,但是的概它们的复杂性和高入门级别要求对简单的转换进行大量编码,并且除了少数程序员外,所有人都不能参与。

参考文章

Chapter 18. Boost.Lexical_Cast 1.0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值