MFC下的常用字符串數據類型表示的含義:
L:Long 長 P:Point 指針 C:Const 常量 W:Wchar_t 寬字符 T:TCHAR STR:String 字符串
在看看MFC下各種數據類型的定義:
1 typedef char *LPSTR; 2 typedef const char *LPCSTR; 3 4 typedef wchar_t *LPWSTR; 5 typedef const wchar_t *LPCWSTR; 6 typedef wchar_t WCHAR; 7 8 #ifdef UNICODE 9 typedef LPCWSTR LPCTSTR; 10 typedef WCHAR TCHAR; 11 12 #else 13 typedef LPCSTR LPCTSTR; 14 typedef char TCHAR;
MFC下提供的ATL 轉換宏:
T2A T2W T2CA T2CW W2A W2CA W2T W2CT A2W A2CW A2T A2CT
T:TCHAR 2:To C:CONST A:CHAR(ANSI) W:WCHAR
先到atlconv.h頭文件下看看這些宏的定義,
1.USES_CONVERSION:注意int _convert; (_convert);這種用法是為了屏蔽編譯器的警告:未引用的局部變量。。。
#ifndef _DEBUG #define USES_CONVERSION int _convert; (_convert); UINT _acp = ATL::_AtlGetConversionACP() /*CP_THREAD_ACP*/; (_acp); LPCWSTR _lpw; (_lpw); LPCSTR _lpa; (_lpa) #else #define USES_CONVERSION int _convert = 0; (_convert); UINT _acp = ATL::_AtlGetConversionACP() /*CP_THREAD_ACP*/; (_acp); LPCWSTR _lpw = NULL; (_lpw); LPCSTR _lpa = NULL; (_lpa) #endif
可見,USES_CONVERSION宏定義了一些轉換所需要的變量,如_convert。所以使用那些宏的時候必須加上該宏。
2.A2W:這里就用到了USES_CONVERSION宏定義的_convert變量
1 #define A2W(lpa) (\ 2 ((_lpa = lpa) == NULL) ? NULL : (\ 3 _convert = (lstrlenA(_lpa)+1),\ 4 (INT_MAX/2<_convert)? NULL : \ 5 ATLA2WHELPER((LPWSTR) alloca(_convert*sizeof(WCHAR)), _lpa, _convert, _acp)))
3.ATLA2WHELPER
1 #define ATLA2WHELPER AtlA2WHelper
4.AtlA2WHelper:實際上還是在調用MultiByteToWideChar,即多字節轉換為寬字節
1 _Ret_opt_z_cap_(nChars) inline LPWSTR WINAPI AtlA2WHelper(_Out_z_cap_(nChars) LPWSTR lpw, _In_z_ LPCSTR lpa, _In_ int nChars, _In_ UINT acp) throw() 2 { 3 ATLASSERT(lpa != NULL); 4 ATLASSERT(lpw != NULL); 5 if (lpw == NULL || lpa == NULL) 6 return NULL; 7 *lpw = '\0'; 8 int ret = MultiByteToWideChar(acp, 0, lpa, -1, lpw, nChars); 9 if(ret == 0) 10 { 11 ATLASSERT(FALSE); 12 return NULL; 13 } 14 return lpw; 15 }
5.alloca
#define alloca _alloca
6._alloca:該函數從堆上分配以字節為單位的內存,返回void *
1 void *_alloca( 2 size_t size 3 );
使用方法舉例:
1 USES_CONVERSION;//USES_CONVERSION是ATL中的一個宏定義,用於編碼轉換,它定義了轉換宏所需的一些局部變量 2 3 WCHAR *pWch = L"WCHAR* TO CHAR*"; 4 CHAR *pCh = W2A(pWch); 5 6 TCHAR *pTch = _T("TCHAR* TO CHAR*"); 7 CHAR *pCh2 = T2A(pTch);
使用USES_CONVERSION一定要小心,它們從堆棧上分配內存,直到調用它的函數返回,該內存不會被釋放。如果在一個循環中,這個宏被反復調用幾萬次,將不可避免的產生stackoverflow。
但是考慮到棧空間的尺寸( 默認2M),使用時要注意幾點:
1、只適合於進行短字符串的轉換;
2、不要試圖在一個次數比較多的循環體內進行轉換;
3、不要試圖對字符型文件內容進行轉換,因為文件尺寸一般情況下是比較大的;
4、對情況 2 和 3,要使用 MultiByteToWideChar() 和 WideCharToMultiByte();
參見http://www.cnblogs.com/wind-net/archive/2012/10/31/2718329.html
5、將字符轉換封裝到函數里面
1 void DoA2W() 2 { 3 USES_CONVERSION; 4 DoSomething(A2W("SomeString")); 5 }
除此之外,還可以使用C語言<stdlib.h>提供的函數:
1 char * pstr = "abc"; 2 3 size_t nLen = _mbstrlen(pstr) + 1; 4 //也可以用mbstowcs(NULL, pstr, 0);,第一個和第三個參數為空即得到非空字符的長度 5 6 wchar_t * pwstr = new wchar_t[nLen]; 7 mbstowcs(pwstr, pstr, nLen);//multibyte string to widechar string 8 9 size_t nwLen = wcslen(pwstr) + 1;//wcstombs(NULL, pwstr, 0) 10 char *pstr2 = new char[nwLen]; 11 wcstombs(pstr2, pwstr, nwLen);//widechar string to multibyte string 12 13 delete []pwstr; 14 pwstr = NULL; 15 16 delete []pstr2; 17 pstr2 = NULL;