C++ Boost 之Lexical_cast

翻译 2003年07月21日 08:14:00

c++boost.gif (8819 bytes)Header boost/lexical_cast.hpp


动机

在很多时候我们必须要把一个值转成字符,就像int表现为一个string,或者相反,一个string被解释成一个int. 当需要在程序内部或者程序外部将数据在各种类型之间转换的时候这样的例子很常见,比如windows和配置文件.

标准C和C++提供了很多灵巧的转换方法.可是,他们在易用性、可扩展性、安全性等发面各不相同。

举个例子,以atoi为代表的标准C函数族有着很多的局限。

  • 从字符串到内部数据类型之间的转换只能单向进行。在使用C的库函数反过来转换时,要么选择使用不方便的、安全妥协的sprintf; 要么使用非标准的函数,比如itoa,从而损失了移植性。
  • 可转换的类型范围仅限于内建的数字类型,也就是说 int, long, 和 double。
  • 没有通用的形式来扩展可以转换的类型范围。比如,从string类型转换到复数和有理数。
以strtol为代表的标准C函数有着同样的限制,但是提供了更好的转换过程控制。然而通常来说这样的控制经常是不需要的或者不被使用。scanf函数族提供了更强大的控制,同时也严重缺乏安全性和易用性。

标准C++提供了stringstream来进行转换。它提供了非常多的对I/O和任意类型到字符串转换和格式化的过程控制。但是使用stringstream进行非常简单的转换时显的十分笨拙(需要额外的局部变量、无法内嵌在表达式中)和晦涩(在表达式中使用时需要创建stringstream的临时对象)。Facets对控制文本的表现提供了广泛的概念支持和便捷,但是它相关的高门槛对于简单的转换来说需要非常高度的介入。

lexical_cast模板方法对从任意类型到字符串或者相反的转换提供了方便和一致的形式。对这种转换它所提供的简化带来了表达式级别的便利。对于需要更多介入的转换时,比如需要精度和格式化的控制比 lexical_cast所提供的更紧密,推荐使用常规的stringstream途径。对于从数字到数字的转换, numeric_cast可能会比lexical_cast提供更合理的转换。

 


例子

下面的例子将命令行参数转换成一个数字序列
int main(int argc, char * argv[])
{
    using boost::lexical_cast;
    using boost::bad_lexical_cast;

    std::vector<short> args;

    while(*++argv)
    {
        try
        {
            args.push_back(lexical_cast<short>(*argv));
        }
        catch(bad_lexical_cast &)
        {
            args.push_back(0);
        }
    }
    ...
}
下面的例子将数字数据转换成string
void log_message(const std::string &);

void log_errno(int yoko)
{
    log_message("Error " + boost::lexical_cast<std::string>(yoko) + ": " + strerror(yoko));
}

大纲

库的特征定义在 "boost/lexical_cast.hpp"中:
namespace boost
{
    class bad_lexical_cast;
    template<typename Target, typename Source>
      Target lexical_cast(Source arg);
}
测试用例定义在 "lexical_cast_test.cpp"中.

 


lexical_cast

template<typename Target, typename Source>
  Target lexical_cast(Source arg);
返回将arg流入std::stringstream然后再作为Target对象取出的结果。转换就这样被当前的lexical_context参数化了。如果转换不成功,一个 bad_lexical_cast异常被抛出,否则一个Target对象被返回。

参数和结果类型的要求如下:

  • Source 是可以流输出的,也就是说得提供一个左边是std::ostream对象,右边是一个 参数类型实例的 operator<< 操作符实现。
  • SourceTarget 都得是可拷贝构造的(提供拷贝构造函数) [20.1.3].
  • Target 是可以流输入的,也就是说得提供一个左边是 std::istream 对象右边是 结果类型实例的 operator>> 操作符实现。
  • Target 是可以 默认构造的, 就是说默认初始化一个该类型对象是可能的(提供默认构造函数)[8.5, 20.1.3].
  • Target可赋值的 [23.1].

 


bad_lexical_cast

class bad_lexical_cast : public std::bad_cast
{
public:
    virtual const char * what() const throw();
};
异常用来指示运行时 lexical_cast 的失败。

 


可移植性

至代码和测试框架在Microsoft Visual C++ 6.0, Borland C++ 5.5, 和 GNU g++ 2.91下编译通过为止。在 Microsoft Visual C++ 6.0 和 Borland C++ 5.5下的测试非常成功。除了g++的stream将任何整形都解释为合法的bool类型,而不仅仅是 01 ,的问题以外,其它的测试都毫无问题地通过了。为了支持out-of-the-box g++,不被推荐的标准头文件 <strstream> 将比<sstream> 优先使用。

 


未来的方向

  • 需要一种能提供服务质量控制的机制,例如: 格式化和异常的行为方式。本着简单(便于发布)的原则,当前的版本 去掉了一个早期的实验版本。
  • 宽字符和不兼容的std::basic_string问题迫切需要解决。
  • 需要一个能够在数据类型之间执行do-something-reasonable转换的interpret_cast。举个例子,它将能根据std::numeric_limits<>::is_specializednumeric_castlexical_cast之间自动选择合适的那个。

© Copyright Kevlin Henney, 2000
© 中文翻译 lythm, 2002

实现 boost lexical_cast(基本类型转换)

boost 中的lexical_cast专门用于基本数据类型转换 比如 int float bool double string ,但是使用时必须引入boost 库,如何自己实现一个相似的函数呢,答案...
  • wangweitingaabbcc
  • wangweitingaabbcc
  • 2015年08月05日 15:26
  • 3937

boost::lexical_cast常见用法详解之万能转换

提示: 虽然在c中可是使用类似于atoi之类的函数对字符串转换成整型,但是我们在这儿还是推荐使用这个函数如果转换发生了错误,lexical_cast会抛出一个bad_lexical_cast...
  • qingzai_
  • qingzai_
  • 2015年03月18日 17:11
  • 3917

Boost.Lexical_Cast用法小结

Lexical_Cast是Boost库中的一个小库。专注于简单的类型转换。重要的有三个——lexical_cast,try_lexical_convert,bad_lexical_cast。其中,ba...
  • llpookk
  • llpookk
  • 2015年06月14日 02:59
  • 881

lexical_cast c++

1、字符串->数值 C++代码 #include lexical_cast.hpp>    #include     int main()    {            ...
  • jiafu1115
  • jiafu1115
  • 2014年01月22日 12:12
  • 649

sprintf,lexical_cast,format 三者效率比较

sprintf,lexical_cast,format 三者效率比较 作者: 江淼 Blog: http://blog.csdn.net/jiangfriend 时间: 2007-7-30 00...
  • Jiangfriend
  • Jiangfriend
  • 2007年07月30日 00:44
  • 3890

boost lexical_cast format

Boost中包括五个字符串与文本处理领域的程序库:  【1】两个与c标准库函数功能类似的lexical_cast和format,它们关注与字符串的表示,可以将数值转化为字符串,对输出做精确的格式化。...
  • mmzsyx
  • mmzsyx
  • 2012年11月16日 17:45
  • 4319

<Boost> boost::lexical_cast字面转换和gregorian::date日期

lexical_cast       用于字面值的转换,转换成int,double型,类似atoi函数。 gregorian::date       是boost里面的日期时间,使用gregorian...
  • Meta_Cpp
  • Meta_Cpp
  • 2015年01月05日 15:44
  • 896

boost lexical_cast 字符串数字间的字面转换(学习笔记)

#include /* @brief 实现数字和字符串之间的字面转换 如把123(int)转换成"123"(string) @remark 注意:要转换为数字的字符串不能包含数字、小数点和e/...
  • wzq9706
  • wzq9706
  • 2011年01月25日 22:46
  • 8309

C++ boost之 conversion/lexical_cast

 动 机 有时候,我们必须把一个值转换成字面上一样的其它形式,比说把int型的数值转换成string型字符串,相反把string字   符串转成int型数值也一样。当程序内部数据类型相互转换或者程序内...
  • hexiankun
  • hexiankun
  • 2008年11月09日 18:24
  • 718

c++11实现一个简单的lexical_cast

boost中有一个lexical_cast可以用统一的方式来做基本类型之间的转换,比如字符串到数字,数字到字符串,bool和字符串及数字之间的相互转换。boost::lexical_cast的用法比较...
  • u011135902
  • u011135902
  • 2016年02月19日 11:57
  • 681
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C++ Boost 之Lexical_cast
举报原因:
原因补充:

(最多只允许输入30个字)