前言
在实际工作中,经常需要对类型进行转换,如string类型的数据转为基本数据类型类型、wstring类型的数据转为基本数据类型,而C++中为我们提供了丰富的对应函数对其支持,但是,在使用的时候,一些细节需要注意。
例子
例如:将string类型的数据转为double类型
stod函数是c++11中支持新增的函数,支持将string类型转换为double精度的浮点数。
//在linux下获取指定进程内存使用率。
string getProMemRate(string ProcessName)
{
if(ProcessName=="")
{
return "null";
}
FILE *fp=NULL;
string cmd="ps aux|grep ";
cmd+=ProcessName;
cmd+="|grep -v grep|awk '{printf $4}'";
fp=popen(cmd.c_str(),"r");
char buf[100];//此处初始化,就可省略后面的memset函数
string memRate="null";
if(!fp)
{
cout<<"get "<<ProcessName<<" Memory Rate Failed!"<<endl;
return "";
}
while(memset(buf,0,sizeof(buf)),fgets(buf,sizeof(buf)-1,fp)!=0)
{
memRate=buf;
}
pclose(fp);
return memRate;
}
但是,对外的接口,内存使用率为double类型,这就需要进行类型转换了。
假如,对函数了解不是很深入时,直接采用如下做法:
double ProMemRate=0;
ProMemRate=stod(getProMemRate(ProcessName)); //ProcessName为参数传递进来的进程名
当getProMemRate函数返回的结果为null或者为空时,就会出现如下错误:
linux下:
terminate called after throwing an instance of 'std::invalid_argument'
what(): stod
已放弃(吐核)
windows下:
分析
查看函数的源码可以发现:
inline double stod(const string& _Str, size_t *_Idx = 0)
{ // convert string to double
const char *_Ptr = _Str.c_str();
errno = 0;
char *_Eptr;
double _Ans = _CSTD strtod(_Ptr, &_Eptr);
if (_Ptr == _Eptr)
_Xinvalid_argument("invalid stod argument");
if (errno == ERANGE)
_Xout_of_range("stod argument out of range");
if (_Idx != 0)
*_Idx = (size_t)(_Eptr - _Ptr);
return (_Ans);
}
当stod函数传进来的字符串参数为空或者参数不是可转换成整数的字符串时,就会如上所示抛出异常,在两种平台(windows和linux)下就会出现前文所示的错误提示。
解决
当我们在对此函数进行应用时,应该首先判断字符串非空或参数不是可转换成整数的字符串的时候再使用stod函数。但是,有时候我们无法考虑所有情况,这时,最好考虑异常进行处理,避免程序出现如前所示异常导致程序运行终止的情况。如下所示:
double ProMemRate=0;
try{
ProMemRate=stod(getProMemRate(ProcessName)); //ProcessName为参数传递进来的进程名
}
catch (const exception& e)
{
cout << "ex: " << e.what() << endl;
}
总结
当然,像stod函数这样的问题,c++中stoi、stol、stoul、stoll、stoull、stof、stold、stoi、stol、stoul、stoull、stof、stold等函数,都会出现如上问题,对应解决办法都是一样。