在windows的開發中,我想,很多人都會遇到字串亂碼;字串拷貝不正確;在已經賦值的字串,另一個字串進行拷貝,發現值不對;或者編碼方式不正確;寬字元,非寬字元等問題;
下面我將統一整理下這下問題,把常用的一些CString,std::string,std::wstring,char,TCHAR,WCHAR的一些相關函數和轉換的關係進行整理。
先介紹幾種在windows開發中,常用的幾種字串類型
char是類型TCHAR也是!不過他可以通過是否定義了UNICODE宏來判斷到底是char還是w_char;
TCHAR是一種字串類型,它讓你在以MBCS和UNNICODE來build程式時可以使用同樣的代碼,不需要使用繁瑣的宏定義來包含你的代碼,而char代表ASCII的字元
基本類型#ifndef VOID#define VOID voidtypedef char CHAR;typedef short SHORT;typedef long LONG;#endif
如果定義了宏ANSI(單位元組)
//// ANSI (Multi-byte Character) types//typedef CHAR *PCHAR, *LPCH, *PCH;typedef CONST CHAR *LPCCH, *PCCH;typedef __nullterminated CHAR *NPSTR, *LPSTR, *PSTR;typedef __nullterminated PSTR *PZPSTR;typedef __nullterminated CONST PSTR *PCZPSTR;typedef __nullterminated CONST CHAR *LPCSTR, *PCSTR;typedef __nullterminated PCSTR *PZPCSTR;
也即,
(1)LPSTR:即 char *(TCHAR*),指向以'\0'結尾的8位(單位元組)ANSI字元數組指標 >>>>>>>>>> 等價於ANSI下的LPTSTR;
(LPSTR是一個指向以‘\0’結尾的ANSI字元數組的指標,與char*可以互換使用,在win32中較多地使用LPSTR);
(2)LPCSTR:即const char *,CONST CHAR*;
如果定義了宏UNICODE(雙位元組)
typedef WCHAR TCHAR, *PTCHAR;typedef WCHAR TBYTE , *PTBYTE ;typedef LPWSTR LPTCH, PTCH;typedef LPWSTR PTSTR, LPTSTR;typedef LPCWSTR PCTSTR, LPCTSTR;typedef LPUWSTR PUTSTR, LPUTSTR;typedef LPCUWSTR PCUTSTR, LPCUTSTR;typedef LPWSTR LP;
也即,
(1)LPWSTR:即wchar_t *(TCHAR*,WCHAR*),指向'\0'結尾的16位(雙位元組)Unicode字元數組指標 >>>>>>>>>> 等價於UNICODE下的LPTSTR;
(2)LPCWSTR:即const wchar_t *,CONST WCHAR*;
還有個要注意的:
#ifdef UNICODE typedef LPWSTR LPTSTR; typedef LPCWSTR LPCTSTR;#else typedef LPSTR LPTSTR; typedef LPCSTR LPCTSTR;#endif
下面介紹UNICODE與ANSI之間的轉換:
(1)
USES_CONVERSION;1.ANSI->UNICODE: A2W();2.UNICODE->ANSI: W2A();
註:用A2W,或者W2A需要用宏USES_CONVERSION;
(2)用API函數MultiByteToWideChar() 和WideCharToMultiByte()
這兩個函數的應用詳見後文的MultiByteToWideChar() 和WideCharToMultiByte()的運用一文;
下面是TCHAR*,CString,std::string,std::wstring之間的轉換
// ***********************************************************************// * 函數: TransCStringToTCHAR// * 描述:將CString 轉換為 TCHAR*// * author: Justin// * 日期:// ***********************************************************************TCHAR* CString2TCHAR(CString &str){int nLen = str.GetLength();TCHAR* szInfo = new TCHAR[iLen]; // 長度是否需要+1lstrcpy(szInfo, str.GetBuffer(iLen));str.ReleaseBuffer();return szInfo;}
// ***********************************************************************// * 函數: TCHAR2CString// * 描述:將CString 轉換為 TCHAR*// * author: Justin// * 日期:// ***********************************************************************CString TCHAR2CString(TCHAR *szInfo){ //CString strTemp(szInfo); (first) CString strTemp; strTemp.Format(_T("%s"),szInfo); return strTemp;}
// ***********************************************************************// * 函數: TransstringToTCHAR// * 描述:將std::string 轉換為 TCHAR*// * author: Justin// * 日期:// ***********************************************************************TCHAR* string2TCHAR(std::string str){ return str.c_str();}
// ***********************************************************************// * 函數: wstringToTCHAR// * 描述:將std::string 轉換為 TCHAR*(WCHAR*, PCHAR)// * author: Justin// * 日期:// ***********************************************************************TCHAR* wstring2TCHAR(std::wstring wstr){ return wstr.c_str();}
// ***********************************************************************// * 函數: TCHARtostring// * 描述:將std::string 轉換為 TCHAR*(WCHAR*, PCHAR)// * author: Justin// * 日期:// ***********************************************************************std::string wstring2TCHAR(TCHAR* tszInfo){ std::string str(tszInfo);return str;}
// ***********************************************************************// * 函數: CStringToLPSTR// * 描述:將CString 轉換為 LPSTR// * author: Justin// * 日期:// ***********************************************************************LPSTR CStringToLPSTR(CString &str){// LPSTR lpStr = strFileName.GetBuffer(strFileName.GetLength());int nLen = str.GetLength();char* szInfo = new char[nLen]; // 長度是否需要+1strcpy(szInfo, str.GetBuffer(nLen))str.ReleaseBuffer();return szInfo;}// ***********************************************************************// * 函數: CStringToLPWSTR// * 描述:將CString 轉換為 LPWSTR// * author: Justin// * 日期:// ***********************************************************************LPWSTR CStringToLPWSTR(CString &str){// LPSTR lpStr = strFileName.GetBuffer(strFileName.GetLength());int nLen = str.GetLength();WCHAR* szInfo = new WCHAR[nLen]; // 長度是否需要+1wcscpy(szInfo, str.GetBuffer(nLen));str.ReleaseBuffer();return szInfo;}
建議:
(1)在windows的開發中,工程的編碼方式盡量用UNICODE;
(2)盡量使用TCHAR,不用char,WCHAR;
(3)少用W2A,A2W,用多自己的轉換的api函數;