1、字符串→数值
在优快云论坛上经常看到询问如何在字符串类型和数值类型间进行转换的问题,也看到了许多
不同的答案。下面先讨论一下从字符串类型到数值类型的转换。
如何将字符串"123"转换为int类型整数123?答案是,用标准C的库函数atoi;
如果要转换为long类型呢?标准C的库函数atol;
如何将"123.12"转换为double类型呢?标准C的库函数atod;
如果要转换为long double类型呢?标准C的库函数atold;
……
后来有朋友开始使用标准库中的string类,问这个如何转换为数值?有朋友答曰,请先转换为
const char*。我很佩服作答者有数学家的思维:把陌生的问题转化成熟悉的问题。(曾经有一则
笑话,好事者问数学家:知道如何烧水吗?答:知道。把水壶加满水,点火烧。又问:如果水
壶里已经有水了呢?答:先倒掉,就转化为我熟悉的问题了……)
不,不,这样是C的做法,不是C++。那么,C++该怎么做呢?使用Boost Conversion Library
所提供的函数lexical_cast(需要引入头文件boost/lexical_cast.hpp)无疑是最简单方便的。如:
style="PADDING-BOTTOM: 0px"style="PADDING-BOTTOM: 0px"#include
<boost/lexical_cast.hpp>
#include <iostream>
int main()
{
using boost::lexical_cast;
int a = lexical_cast<int>("123");
double b = lexical_cast<double>("123.12");
std::cout<<a<<std::endl
std::cout<<b<<std::endl;
return 0;
}
一个函数就简洁地解决了所有的问题。
3.2数值→字符串
那么从数值类型到字符串类型呢?
用itoa?不对吧,标准C/C++里根本没有这个函数。即使在Windows平台下某些编译器提供了该
函数3,没有任何移植性不说,还只能解决int类型(也许其他函数还可以解决long、unsigned long
等类型),浮点类型又怎么办?当然,办法还是有,那就是:sprintf。
style="PADDING-BOTTOM: 0px"style="PADDING-BOTTOM: 0px"char s[100];
sprintf(s, "%f", 123.123456);
不知道诸位对C里的scanf/printf系列印象如何,总之阿炯我肯定记不住那些稀奇古怪的参数,而
且如果写错了参数,就会得到莫名其妙的输出结果,调试起来可就要命了(我更讨厌的是字符
数组,空间开100呢,又怕太小装不下;开100000呢,总觉得太浪费,心里憋气,好在C++标
准为我们提供了string这样的字符串类)。这时候,lexical_cast就出来帮忙啦。
style="PADDING-BOTTOM: 0px"style="PADDING-BOTTOM: 0px"#include
<boost/lexical_cast.hpp>
#include <string>
#include <iostream>
int main()
{
using std::string;
const double d = 123.12;
string s = boost::lexical_cast<string>(d);
std::cout<<s<<std::endl;
return 0;
}
跟前面一样简单。
3.3异常
如果转换失败,则会有异常bad_lexical_cast抛出。该异常类是标准异常类bad_cast的子类。
style="PADDING-BOTTOM: 0px"style="PADDING-BOTTOM: 0px"#include
<boost/lexical_cast.hpp>
#include <iostream>
int main()
{
using std::cout;
using std::endl;
int i;
try{
i = boost::lexical_cast<int>("abcd");
}
catch(boost::bad_lexical_cast& e)
{
cout<<e.what()<<endl;
return 1;
}
cout<<i<<endl;
return 0;
}
显然“abcd”并不能转换为一个int类型的数值,于是抛出异常,捕捉后输出“bad lexical cast:
source type value could not be interpreted as target”这样的信息。