在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 void typedef char CHAR; typedef short SHORT; typedef long LONG; #endif如果定义了宏ANSI(单字节)
(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]; // 长度是否需要+1 lstrcpy(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]; // 长度是否需要+1 strcpy(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]; // 长度是否需要+1 wcscpy(szInfo, str.GetBuffer(nLen)); str.ReleaseBuffer(); return szInfo; }
建议:
(1)在windows的开发中,工程的编码方式尽量用UNICODE;
(2)尽量使用TCHAR,不用char,WCHAR;
(3)少用W2A,A2W,用多自己的转换的api函数;