boost之字符串--lexical_cast

函数由来

顾名思义,lexical_cast库进行“字面值”的转换,类似c中的atoi()函数,可以进行字符串与整数/浮点数之间的字面转换。

#include<boost/lexical_cast.hpp>

using namespace boost;

我们都很熟悉c语言中的atoi()、atof()系列函数,它们可以把字符串转换成数值,但这种转换是不对称的,不存在如 itoa ()这样的反向转换°,要想把数值转换为字符串,只能使用不安全的printf ()

标准形式:

转化成 数字和字符串

template<typename Target,typename Source>

inline Target  lexical_cast(const Source &arg);

//转化c字符

template<typename Target>

inline Targe lexical_cast(const char* chars,std::size_t count);

函数用法:

  int x           =lexical_cast<int>("100");//string->int
    long y          =lexical_cast<long>("2000");//string->长整数
    float pai       =lexical_cast<float>("3.13159e5");
    double e        =lexical_cast<double>("2,71828");
    double r        =lexical_cast<double>("1.414,x",5);
    
    std::cout<<x<<" "<<y<<" "<<pai<<"   "<<
    e<<"    "<<r<<" ";

    std::string str =lexical_cast<std::string>(456);
    std::cout<<str<<std::endl;

    std::cout<<lexical_cast<std::string>(0.618)<<std::endl;
    std::cout<<lexical_cast<std::string>(0x10)<<std::endl;

//
100 2000 3141592.71828 1.414
456

0.61799999999999999
16

错误处理:

 try{
    int x           =lexical_cast<int>('100');//string->int
    long y          =lexical_cast<long>('2000');//string->长整数
    float pai       =lexical_cast<float>("3.13159e5");
    double e        =lexical_cast<double>("2,71828");
    double r        =lexical_cast<double>("1.414,x",5);
   }

   catch(bad_lexical_cast&e)
   {
        std::cout<<"error: "<<e.what()<<std::endl;
   }

lexical_cast在名字空间boost : : conversion提供try lexical convert ()函数,可以避免抛出异常,它以bool返回值表示是否转换成功。函数的声明是:




int x;
assert(!conversion::try_lexical_convert("0x100",5))

验证数字字符串的合法性

assert( !num_valid<double> ("3.14"));
assert( !num_valid<int> ( "3.14"));
assert (!num_valid<int>("65535"));

应用于自定义类

如果我们想要将lexcical_cast应用于自定义的类,把类转换为可理解的字符串描述(类似于Java语言中的object.tostring ()用法),只需要满足lexcical_cast的要求即可。准确地说,需要实现流输出操作符operator<<。

class dome_class
{
  friend std::ostream& operator<<(std::ostream&os,const demo_class&x)
  { 
os<<"demo_class's Name";
return os;
}

}
std::cout<<lexical_cast<std::string>(demo_calss())<<std::endl;

这段代码具有通用性,值得把它提取为一个模板类。我们可以仿造boost.operator库,定义一个模板类outable,以简化流输出操作符<<的重载。注意,这里没有使用基类链技术,不能用于operator的基类串联,但可以很容易添加这个功能:

template<typename T>
struct outable
{

friend std::ostream&operator<<(std::ostream os,const T& x)
{
 os<<typeid(T).name();// 使用typeid操作符输出类型名字
  return os;
}
}

format

C++输入/输出流也不是完美无瑕的,精确输出的格式控制要写大量的操控函数,而且会改变流的状态,用完后还需要及时恢复,有时候会显得十分烦琐。因此,还是有很多程序员怀念c语言中经典的printf(),虽然它缺乏类型安全检查,还有其他的一些缺点,但它语法简单高效,并且被广泛地接受和使用,影响深远。

format组件位于名字空间boost,需要包含头文件<boost/format.hpp>,即;

#include <boost/ format. hpp>

using namespace boost;

用法:

    std::cout<<format("%s:=%d+%d=%d\n")%"sum"%1%2%(1+2);
    format fmt("(%1%+%2%)*%2%=%3%\n");
    fmt %2%5;
    fmt %((2+5)*5);
    std::cout<<fmt.str();

第一条format语句的等价printf ()调用是

printf ( "%s : %d+%d=%d\n" , " sum", 1,2,(1+2));

format ( ...) << a<< b<<c

操作符%把参数逐个地“喂”给format对象,完成对参数的格式化。

后面的三行语句演示了format 的另一种用法,

预先创建一个format格式化对象,它可以被后面的代码多次用于格式化操作。format对象仍然用操作符%来接受被格式化的参数,可以分多次输入(不必一次给全),但参数的数量必须满足格式化字符串的要求。最后,使用format对象的str ()成员函数获得已格式好的字符串向cout流输出。

第二个format用了略不同于printf()的格式化语法:"(%1%+%2%)* %2%= %3% \n",有点类似c#语言,%N%可以指示参数的位置,减少参数输入的工作——这是对printf()语法的一个改讲,

第二个format对象的等价printf ()调用是

printf ("(%d + %d)* %d = %d\n" ,2,5,5,(2+5)*5);

格式化语法:

%05d:  输出宽度为5的整数,不足位用0填充;

%-8.3f :输出左对齐,总宽度为8,小数位3位的浮点数;

% 10s:输出10位的字符串,不足位用空格填充;

%05x :输出宽度为5的大写十六进制整数,不足位用0填充。

% lspecl     :与printf格式选项功能相同,但两边增加了竖线分隔,可以更好地区分格式化选项与普通字符;

%N% :标记第N个参数,相当于占位符,不带任何其他的格式化选项。

format fmt("%|05d|\n%|-8.3f|\n%l10s|\n%|05X|\n ")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值