char,string,CString相互转换

本文摘抄自http://blog.sina.com.cn/s/blog_7c1a82970100qmwk.html


本人并未对以下所有方法进行测试,仅仅是为了给大家一个参考。

     Unicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。随着计算机工作能力的增强,Unicode也在面世以来的十多年里得到普及。在非 Unicode 环境下,由于不同国家和地区采用的字符集不一致,很可能出现无法正常显示所有字符的情况。微软公司使用了代码页(Codepage)转换表的技术来过渡性的部分解决这一问题,即通过指定的转换表将非 Unicode 的字符编码转换为同一字符对应的系统内部使用的 Unicode 编码。

一、char*与wchar_t*

1、将单字节char* 转换为 宽字节 wchar_t*

wchar_t* cs2wcs( const char* sz )
{
size_t len = strlen( sz ) + 1;
size_t converted = 0;
wchar_t* wsz = (wchar_t*)malloc( len*sizeof(wchar_t) );
mbstowcs_s(&converted, wsz, len, sz, _TRUNCATE);
return wsz;
}
 

2、将宽字节wchar_t* 转换单字节char*
char* wcs2cs( const wchar_t* wsz )
{
size_t len = wcslen(wsz) + 1;
size_t converted = 0;
char* sz = (char*)malloc(len*sizeof(char));
wcstombs_s(&converted, sz, len, wsz, _TRUNCATE);
return sz;

}

 

二、其它数据类型转换为字符串string
1、短整型(int)
itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制
itoa(i,temp,2); ///按二进制方式转换
2、长整型(long)
ltoa(l,temp,10);
3、浮点数(float,double)
用fcvt可以完成转换,这是MSDN中的例子:
int decimal, sign;
char *buffer;
double source = 3.1415926535;
buffer = _fcvt( source, 7, &decimal, &sign );
运行结果:source: 3.1415926535 buffer: '31415927' decimal: 1 sign: 0
decimal表示小数点的位置,sign表示符号:0为正数,1为负数
4、CString变量
str = "2008北京奥运";
非Unicode
①buf = (LPSTR)(LPCTSTR)str;
②string buf(str.Getbuffer());
str.ReleaseBuffer();
Unicode
先转成char*,再直接赋值

5、BSTR变量
BSTR bstrValue = ::SysAllocString(L"程序员");
char * buf = _com_util::ConvertBSTRToString(bstrValue);
SysFreeString(bstrValue);
AfxMessageBox(buf);
delete(buf);
6、CComBSTR变量
CComBSTR bstrVar("test");
char *buf = _com_util::ConvertBSTRToString(bstrVar.m_str);
AfxMessageBox(buf);
delete(buf);
7、_bstr_t变量
_bstr_t类型是对BSTR的封装,因为已经重载了=操作符,所以很容易使用
_bstr_t bstrVar("test");
const char *buf = bstrVar;///不要修改buf中的内容
AfxMessageBox(buf);

通用方法(针对非COM数据类型)
sprintf完成转换
char buffer[200];
char c = '1';
int   i = 35;
long j = 1000;
float f = 1.7320534f;
sprintf( buffer, "%c",c);
sprintf( buffer, "%d",i);
sprintf( buffer, "%d",j);
sprintf( buffer, "%f",f);

 

三、字符串string转换为其它数据类型
temp="123456";
1、短整型(int)
i = atoi(temp);
2、长整型(long)
l = atol(temp);
3、浮点(double)
d = atof(temp);
string s; d= atof(s.c_str());
4、BSTR变量
BSTR bstrValue = ::SysAllocString(L"程序员");
...///完成对bstrValue的使用
SysFreeString(bstrValue);
5、CComBSTR变量
CComBSTR类型变量可以直接赋值
CComBSTR bstrVar1("test");
CComBSTR bstrVar2(temp);
6、_bstr_t变量
_bstr_t类型的变量可以直接赋值
_bstr_t bstrVar1("test");
_bstr_t bstrVar2(temp);

7、string转char*

string 是c++标准库里面其中一个,封装了对字符串的操作
把string转换为char* 有3中方法:
(1)data 
stringstr="abc";
char *p=str.data();
(2)c_str

string str="gdfd";
    char *p=str.c_str();
(3)copy 
string str="hello";
char p[40];
str.copy(p,5,0); //这里5,代表复制几个字符,0代表复制的位置
*(p+5)='\0'; //要手动加上结束符
cout < <p;

8、string转wchar_t

#include <stdlib.h>

string str = "hello";
wchar_t* wsz;
wsz = new wchar_t[str.size()];
mbstowcs(wsz, str.c_str(),str.size());

 

四、CString与其他数据类型之间的转换

1、其它数据类型转换到CString
使用CString的成员函数Format来转换,例如:
整数(int)           str.Format("%d",i);
浮点数(float)    str.Format("%f",i); doubledb = 777.999; str.Format("%.8f",db); 保留8位小数
字符串指针(char *)可以直接赋值str = username;
对于Format所不支持的数据类型,可以通过上面所说的关于其它数据类型转化到char *的方法先转到char *,然后赋值给CString变量。
注意:MFC智能设备string转Cstring
   string s=”123456”;   CString cstr;   cstr=s.c_str();

2、CString 转double或float

(1)db = atof((LPCTSTR)str);

(2)通过自定义函数实现

void CStringToFloat(CString cstr ,double &f )//void CStringToFloat(CString cstr ,float&f )
{
int nLength = cstr.GetLength();
int nBytes = WideCharToMultiByte(CP_ACP,0,cstr,nLength,NULL,0,NULL,NULL);
char* pContentBuff = new char[ nBytes + 1];
memset(pContentBuff,0,nBytes+1);
WideCharToMultiByte(CP_OEMCP, 0, cstr, nLength, pContentBuff, nBytes, NULL, NULL);
pContentBuff[nBytes] = 0;
f = atof(pContentBuff);
}

3、CString转int

CString如何转成int网上的介绍都是用atoi函数,但是CString 内部存储的是wchar_t 类型的字符,每个字符占两个字节,atoi的参数是char*,每个字符占一个字节 ,如果强制转换成char*,由于高位字节是空,所以就转成了只有第一个字符的串,这样是不对的.应该用_wtoi函数,这个函数的参数是wchar_t*,示例如下:
CString str("123");
int num = _wtoi(str);
同样,也有_wtof(),_wtol()等函数可供将CString 转成不同的数值类型.

4、编译器使用Unicode字符集时,CString类型转换为char*或char[ ]
(1)

CString origCString("Hello, World!");
wchar_t* wCharString = origCString.GetBuffer(origCString.GetLength()+1);
size_t origsize = wcslen(wCharString) + 1;
size_t convertedChars = 0;
char *CharString;
CharString=new char(origsize);
wcstombs_s(&convertedChars, CharString, origsize, wCharString , _TRUNCATE);

(2)

USES_CONVERSION; // 这个宏在atlbase.h中定义。
CString testText = _T("你好测试文本"); // 注意这里你不用管他是unicode还是ansi
TCHAR* tcPtr = testText.GetBuffer(); // unicode返回wchar_t* ,ansi返回char*
char*p = T2A(tcPtr); // 这里你就会得到你最终想要的char* 了, 不管是unicode还是ansi下这样写肯定不会乱码了.

使用Unicode时,直接

USES_CONVERSION; // 这个宏在atlbase.h中定义。
CString testText = _T("你好测试文本"); char*p = T2A(testText);

(3)

wstring MultCHarToWideChar(string str)
{
//获取缓冲区的大小,并申请空间,缓冲区大小是按字符计算的
int len=MultiByteToWideChar(CP_ACP,0,str.c_str(),str.size(),NULL,0);
TCHAR *buffer=new TCHAR[len+1];
//多字节编码转换成宽字节编码
MultiByteToWideChar(CP_ACP,0,str.c_str(),str.size(),buffer,len);
buffer[len]='\0';//添加字符串结尾
//删除缓冲区并返回值
wstring return_value;
return_value.append(buffer);
delete []buffer;
return return_value;
}
string WideCharToMultiChar(wstring str)
{
string return_value;
//获取缓冲区的大小,并申请空间,缓冲区大小是按字节计算的
int len=WideCharToMultiByte(CP_ACP,0,str.c_str(),str.size(),NULL,0,NULL,NULL);
char *buffer=new char[len+1];
WideCharToMultiByte(CP_ACP,0,str.c_str(),str.size(),buffer,len,NULL,NULL);
buffer[len]='\0';
//删除缓冲区并返回值
return_value.append(buffer);
delete []buffer;
return return_value;
}
于是使用
string mstring = WideCharToMultiChar( (LPCTSTR)mCString );
strcpy_s( pach, sizeof(pach), mstring.c_str() );
转换成功!

 

 

五、BSTR、_bstr_t与CComBSTR
CComBSTR 是ATL对BSTR的封装,_bstr_t是C++对BSTR的封装,BSTR是32位指针,但并不直接指向字串的缓冲区。
char *转换到BSTR可以这样:
BSTR b=_com_util::ConvertStringToBSTR("数据");///使用前需要加上comutil.h和comsupp.lib
SysFreeString(bstrValue);
反之可以使用char *p=_com_util::ConvertBSTRToString(b);delete p;

CComBSTR与_bstr_t对大量的操作符进行了重载,可以直接进行=,!=,==等操作,所以使用非常方便。

 

六、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与常用数据的对应关系:
Byte 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.
DECIMAL FAR* pdecVal // VT_BYREF|VT_DECIMAL.
IUnknown FAR* punkVal; // VT_UNKNOWN.
IDispatch FAR* pdispVal; // VT_DISPATCH.
SAFEARRAY FAR* parray; // VT_ARRAY|*.
Byte 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; // Generic ByRef.
char cVal; // VT_I1.
unsigned short uiVal; // VT_UI2.
unsigned long ulVal; // VT_UI4.
int intVal; // VT_INT.
unsigned int uintVal; // VT_UINT.
char FAR * pcVal; // VT_BYREF|VT_I1.
unsigned short FAR * puiVal; // VT_BYREF|VT_UI2.
unsigned long FAR * pulVal; // VT_BYREF|VT_UI4.
nt FAR * pintVal; // VT_BYREF|VT_INT.
unsigned int FAR * puintVal; //VT_BYREF|VT_UINT.
_variant_t是VARIANT的封装类,其赋值可以使用强制类型转换,其构造函数会自动处理这些数据类型。
使用时需加上#include <comdef.h>
例如:
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;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值