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;