函数由来
顾名思义,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 ")