C++常用数据类型转换详解

时间:2022-02-01 20:18:45

转自:http://hi.baidu.com/zhenlu_123/blog/item/b744dd3c3e5180e63c6d97eb.html

 

我们先定义一些常见类型变量借以说明:

int i = 100;
long l = 2001;
float f=300.2;
double d=12345.119;
char username[]="女侠程佩君";
char temp[200];
char *buf;
CString str;
_variant_t v1;
_bstr_t v2;

一、其它数据类型转换为字符串

短整型(int)

itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制
itoa(i,temp,2); ///按二进制方式转换

长整型(long)

ltoa(l,temp,10);
二、从其它包含字符串的变量中获取指向该字符串的指针

CString变量

str = "2008北京奥运";
buf = (LPSTR)(LPCTSTR)str;

BSTR类型的_variant_t变量

v1 = (_bstr_t)"程序员";
buf = _com_util::ConvertBSTRToString((_bstr_t)v1);

三、字符串转换为其它数据类型

strcpy(temp,"123");
短整型(int)

i = atoi(temp);
长整型(long)

l = atol(temp);
浮点(double)

d = atof(temp);
四、其它数据类型转换到CString

使用CString的成员函数Format来转换,例如:

整数(int)

str.Format("%d",i);
浮点数(float)

str.Format("%f",i);
字符串指针(char *)等已经被CString构造函数支持的数据类型可以直接赋值

str = username;
五、BSTR、_bstr_t与CComBSTR

CComBSTR、_bstr_t是对BSTR的封装,BSTR是指向字符串的32位指针。

char *转换到BSTR可以这样: BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上头文件comutil.h

反之可以使用

char *p=_com_util::ConvertBSTRToString(b);
六、VARIANT 、_variant_t 与 COleVariant

VARIANT的结构可以参考头文件VC98/Include/OAIDL.H中关于结构体tagVARIANT的定义。

对于VARIANT变量的赋值:首先给vt成员赋值,指明数据类型,再对联合结构中相同数据类型的变量赋值,举个例子:

VARIANT va;
int a=2001;
va.vt=VT_I4;///指明整型数据
va.lVal=a; ///赋值

对于不马上赋值的VARIANT,最好先用Void VariantInit(VARIANTARG FAR* pvarg);进行初始化,其本质是将vt设置为VT_EMPTY,下表我们列举vt与常用数据的对应关系:

unsigned char bVal; VT_UI1
short iVal; VT_I2
long lVal; VT_I4
float fltVal; VT_R4
double dblVal; VT_R8
VARIANT_BOOL boolVal; VT_BOOL
SCODE scode; VT_ERROR
CY cyVal; VT_CY
DATE date; VT_DATE
BSTR bstrVal; VT_BSTR
IUnknown FAR* punkVal; VT_UNKNOWN
IDispatch FAR* pdispVal; VT_DISPATCH
SAFEARRAY FAR* parray; VT_ARRAY|*
unsigned char FAR* pbVal; VT_BYREF|VT_UI1
short FAR* piVal; VT_BYREF|VT_I2
long FAR* plVal; VT_BYREF|VT_I4
float FAR* pfltVal; VT_BYREF|VT_R4
double FAR* pdblVal; VT_BYREF|VT_R8
VARIANT_BOOL FAR* pboolVal; VT_BYREF|VT_BOOL
SCODE FAR* pscode; VT_BYREF|VT_ERROR
CY FAR* pcyVal; VT_BYREF|VT_CY
DATE FAR* pdate; VT_BYREF|VT_DATE
BSTR FAR* pbstrVal; VT_BYREF|VT_BSTR
IUnknown FAR* FAR* ppunkVal; VT_BYREF|VT_UNKNOWN
IDispatch FAR* FAR* ppdispVal; VT_BYREF|VT_DISPATCH
SAFEARRAY FAR* FAR* pparray; VT_ARRAY|*
VARIANT FAR* pvarVal; VT_BYREF|VT_VARIANT
void FAR* byref; VT_BYREF

_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。

例如:

long l=222;
ing i=100;
_variant_t lVal(l);
lVal = (long)i;

COleVariant的使用与_variant_t的方法基本一样,请参考如下例子:

COleVariant v3 = "字符串", v4 = (long)1999;
CString str =(BSTR)v3.pbstrVal;
long i = v4.lVal;

七、其它

对消息的处理中我们经常需要将WPARAM或LPARAM等32位数据(DWORD)分解成两个16位数据(WORD),例如:

LPARAM lParam;
WORD loValue = LOWORD(lParam);///取低16位
WORD hiValue = HIWORD(lParam);///取高16位

对于16位的数据(WORD)我们可以用同样的方法分解成高低两个8位数据(BYTE),例如:

WORD wValue;
BYTE loValue = LOBYTE(wValue);///取低8位
BYTE hiValue = HIBYTE(wValue);///取高8位

 

 

 

用标准C++进行string与各种内置类型数据之间的转换

收藏




要实现这个目标,非stringstream类莫属。这个类在<sstream>头文件中定义,

<sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本。简单起见,我主要以stringstream为中心,因为每个转换都要涉及到输入和输出操作。示例1示范怎样使用一个stringstream对象进行从

string到int类型的转换

注意,<sstream>使用string对象来代替字符数组。这样可以避免缓冲区溢出的危险。而且,传入参数和目标对象的类型被自动推导出来,即使使用了不正确的格式化符也没有危险。

示例1:

std::stringstream stream;

string result="10000";
int n = 0;
stream << result;
stream >> n;//n等于10000

int到string类型的转换

string result;
int n = 12345;
stream << n;
result =stream.str();// result等于"12345"

重复利用stringstream对象

如果你打算在多次转换中使用同一个stringstream对象,记住再每次转换前要使用clear()方法,在多次转换中重复使用同一个stringstream(而不是每次都创建一个新的对象)对象最大的好处在于效率。stringstream对象的构造和析构函数通常是非常耗费CPU时间的。经试验,单单使用clear()并不能清除stringstream对象的内容,仅仅是了该对象的状态,要重复使用同一个stringstream对象,需要使用str()重新初始化该对象。

示例2:

std::stringstream strsql;
for (int i= 1; i < 10; ++i)
{
strsql << "insert into test_tab values(";
   strsql << i << ","<< (i+10) << ");";
   std::string str = strsql.str(); // 得到string
   res = sqlite3_exec(pDB,str.c_str(),0,0, &errMsg);

   std::cout << strsql.str() << std::endl;

   strsql.clear();
   strsql.str("");
}

转换中使用模板

也可以轻松地定义函数模板来将一个任意的类型转换到特定的目标类型。例如,需要将各种数字值,如int、long、double等等转换成字符串,要使用以一个string类型和一个任意值t为参数的to_string()函数。to_string()函数将t转换为字符串并写入result中。使用str()成员函数来获取流内部缓冲的一份拷贝:

示例3:

template<class T>

void to_string(string & result,const T& t)

{

ostringstream oss;//创建一个流

oss<<t;//把值传递如流中

result=oss.str();//获取转换后的字符转并将其写入result
}

这样,你就和衣轻松地将多种数值转换成字符串了:

to_string(s1,10.5);//double到string

to_string(s2,123);//int到string

to_string(s3,true);//bool到string

可以更进一步定义一个通用的转换模板,用于任意类型之间的转换。函数模板convert()含有两个模板参数out_type和in_value,功能是将in_value值转换成out_type类型:

template<class out_type,class in_value>

out_type convert(const in_value & t)

{

stringstream stream;

stream<<t;//向流中传值

out_type result;//这里存储转换结果

stream>>result;//向result中写入值

return result;

}

这样使用convert():

double d;

string salary;

string s=”12.56”;

d=convert<double>(s);//d等于12.56

salary=convert<string>(9000.0);//salary等于”9000”

结论

 

在过去留下来的程序代码和纯粹的C程序中,传统的<stdio.h>形式的转换伴随了我们很长的一段时间。但是,如文中所述,基于stringstream的转换拥有类型安全和不会溢出这样抢眼的特性,使我们有充足得理由抛弃<stdio.h>而使用<sstream>。

当然现在还有一个更好的选择,那就是使用boost库中的lexical_cast,它是类型安全的转换。如下例:

#include <iostream>

#include <sstream>

#include <string>

#include <cstdlib>

#include <boost/lexical_cast.hpp>

using namespace std;

using namespace boost;

int main(void)

try{

   //以下是内置类型向string转换的解决方案

   //lexical_cast优势明显

       int ival;

       char cval;

       ostringstream out_string;

       string str0;

       string str1;

      

       ival = 100;

       cval = 'w';

       out_string << ival << " " << cval;

       str0 = out_string.str();

       str1 = lexical_cast<string>(ival)

                   + lexical_cast<string>(cval);

       cout << str0 << endl;

       cout << str1 << endl;

    //以下是string向内置类型转换的解决方案

    //几乎和stringstrem相比,lexical_cast就是类型安全的,

       int itmpe;

       char ctmpe;

       str0 = "100k";

       str1 = "100h";

    istringstream in_string( str0 );

       in_string >> itmpe >> ctmpe;

       cout << itmpe << " " << ctmpe << endl;

     itmpe = lexical_cast<int>(str1);

     ctmpe = lexical_cast<char>(str1);

       system( "PAUSE" );

       return 0;

}

catch(bad_lexical_cast e)

{

    cout << e.what() << endl;

    cin.get();

}       

 

 

# roger007 发表于2006-10-19 22:06:00   IP: 218.79.103.*
使用STL实现C++所有数据类型转换为字符串型的to_string函数
及string 到其它数据类型的转换函数

1.数据类型转换为字符串型的to_string函数
template< class T>
inline std::string to_string( const T & Value)
{
std::stringstream streamOut;
streamOut << Value;
return streamOut.str( );
}

// 对原数据类型为string类型的特殊处理
template< >
inline std::string to_string( const std::string & Value)
{
return Value;
}

该函数对所有C++内有数据类型均适用。对支持“<<”运算符的类同样适用。

当然,实现与to_string功能相反的函数也是容易的。

2.string 到其它数据类型的转换函数
template< class T>
inline T from_string( const std::string & ToConvert)
{
std::stringstream streamIn( ToConvert);
T ReturnValue = T( );
streamIn >> ReturnValue;
return ReturnValue;
}

from_string函数将字符串转化为某一类型。例如,它可以将字符串转化为数据。如果输入有效,本函数将转换并返回它。另外,该函数返回指定的类型的默认值,T()为默认的构造函数。还有,它适用与任何C++内有的数据类型,对任何默认构造函数实现了“>>”操作符的类也同样适用。

注意from_string函数假定你转换的字符串中仅有一个值,任何多余的值都将被忽略。如果字符串有多值并且都是你需要的,请勿使用form_string函数,你可以从流中(直接)读取它们。

3.使用这两个转换函数:
下面的例子说明了如何使用上述的两个函数:

int n = 4;
std::string str = to_string( n); // "4"
long l = 534587;
str = to_string( l); // "534587"
n = from_string< int>( "a"); // 0
int nTest = from_string< int>( "5744"); // 5744
int nTest2 = from_string< int>( "57y4"); // 57
int nTest3 = from_string< int>( "5743 65"); // 5743; 65 igno