在 C 语言中提供了几个标准库函数,可以将字符串与整型,浮点型等进行转换。
atof() 将字符串转换为双精度浮点型值
atoi() 将字符串转换为整型值
atol() 将字符串转换为长整型值
itoa() 将整型值转换为字符串
gcvt() 将浮点数类型值转换为字符串
C/C++ 中提供的像 atoi,itoa,atof,gcvt 等这些函数都是可以实现字符串和数值转换的,但是问题在于接口不统一,需要记的东西太多。特别是像 gcvt 这样的,很难记住是浮点类型转换为字符串类型。
使用 stringstream 对象简化类型转换
C++ 标准库中的 提供了比 ANSI C 的 <stdio.h> 更高级的一些功能,即单纯性,类型安全和可扩展性。
举个例子,现在如果想要将一个整数转换为 char 数组(类似于字符串)类型,可以使用 sprintf,但是如果你在调用的时候错误地使用了转换符,将会导致不可预知的结果。
可以使用 stringstream 来进行转换,stringstream 转换好的结果保存在 stringstream 对象的内部缓冲中,不必担心缓冲区溢出,因为这些对象会自动分配存储空间。
使用前包含 <sstream> 头文件,<sstream>库定义了三种类:istringstream,ostringstream 和 stringstream,分别用来进行流的输入,输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本。下面主要以 stringstream 为中心,因为每个转换都要涉及到输入和输出操作。
如果你打算在多次转换中使用同一个 stringstream 对象,记住再每次转换前要使用 clear() 方法,在多次转换中重复使用同一个 stringstream(而不是每次都创建一个新的对象)对象最大的好处在于效率。stringstream 对象的构造和析构函数通常是非常耗费时间的。关于 stringstream 的更多用法参考:https://www.cnblogs.com/snowbook/p/5964434.html
boost 库中的 lexical_cast 为数值之间的转换提供了一个更好的解决方案,而且在转换失败的时候 lexical_cast 会抛出一个 bad_lexical_cast 的异常,用户可以使用 try-catch 去捕获处理这个异常。
使用 lexical_cast 函数模板需要包含 boost\lexical_cast.hpp 这个头文件,然后 using namespace boost::lexical_cast 就可以直接使用 lexical_cast 模板函数了。
lexical_cast 是一个模板函数,如果需要将字符串转换为 int 类型,那么在 <> 实例化传入 int 类型即可,即 <int> 或者 <float> 代表要将后面的字符串或者数字转为相应的类型,如果转换失败会抛出异常,可以使用 catch 去接收(先 using boost::bad_lexical_cast,然后在 catch 形参里指定接收类型为 bad_lexical_cast)。
lexical_cast使用统一的接口实现字符串与目标类型之间的转换。
二、lexical_cast与c/c++提供类似接口的比较
标准c家族中包含此类函数,例如atoi与itoa等,它们的缺点是:
(1)各个转换都是单向的,双向转换为不同函数,各种转换函数不同,接口众多;
(2)仅支持基础数据类型的子集,如int,long,double;
(3)不能提供统一的接口,易用性差;
c++中提供了stringstream,使用它进行格式转换可读性较差,使用起点较高,只是简单的转换,stringstream太重量级。
boost提供了lexical_cast,使用统一接口形式实现任意类型之间的转换,增强了易用性。**但如果需要严密控制精度的转换,仍然推荐使用stringstream;**数值之间的转换,推荐使用numeric_cast。
好像可以修改lexical_cast头文件来解决控制精度问题
四、lexical_cast的样例代码
#include "iostream"
#include "boost/lexical_cast.hpp" // 需要包含的头文件
using boost::lexical_cast;
using boost::bad_lexical_cast;
using namespace std;
int main()
{
char* p="32768";
int i=0;
try
{
i=lexical_cast<int>(p); // 将字符串转化为整数
}
catch(bad_lexical_cast&) // 转换失败会抛出一个异常
{
i=0;
}
cout << i << endl;
return i;
}