一. ANSI窄字节和Unicode宽字节
- 产生原因:本来只有ANSI,用1个字节存放1个字符,但是,汉字和全角字符用1个字节存放不下,为此,微软推出了Unicode字节,用2个字节来存放字符。
- 代码体现:
1 //ANSI窄字节 2 CHAR cData1 = ‘a‘;//char 3 PCHAR pcData2 = "abc";//char* 4 PSTR pstrData3 = "def";//char* 5 LPSTR lpData4 = "ghi";//char* 6 LPCSTR lpcData5 = "okz"; //const char* 7 printf("ANSI: %d \n", (strlen(lpcData5) + 1) * sizeof (CHAR));//4 8 9 //Unicode宽字节 10 WCHAR cData6 = ‘a‘; //wchar_t 11 PWCHAR pcData7 = L"abc";//wchar_t* 12 PWSTR pstrData8 = L"def";//wchar_t* 13 LPWSTR lpData9 = L"ghi";//wchar_t* 14 LPCWSTR lpcData10 = L"okz";//const wchar_t* 15 printf("Unicode: %d \n", (wcslen(lpcData10) + 1) * sizeof (WCHAR));//8 16 17 //通用字节:根据项目-->字符集:多字节/Unicode自动切换 18 TCHAR cData11 = ‘a‘;// char or wchar_t 19 //PTCHAR pcData12 = _T("abc");// char* or wchar_t* _TCHAR_DEFINED未定义时可使用 20 PTSTR pstData13 = _T("def");// char* or wchar_t* 21 LPTSTR lpData14 = _T("ghi");// char* or wchar_t* 22 LPCTSTR lpcData15 = _T("okz");//const char* or const wchar_t* 23 printf("ANSI OR Unicode: %d \n", (_tcslen(lpcData15) + 1) * sizeof (TCHAR));//字符集为Unicode:8
- 相互转换:为什么要转换?理论上使用Unicode就好了,但是Unicode比ANSI占用的内存空间多一倍,当传输并行且数据量大时,使用ANSI性能更高效。
- 方式1:使用 WideCharToMultiByte 和 MultiByteToWideChar 实现
1 //代码页-----CP_ACP:C++代码用的 UTF-8:网页用的 2 /*=====================wchar_t*===>char*============================*/ 3 char* w2a(wchar_t* lpszSrc, UINT CodePage = CP_ACP) 4 { 5 if (lpszSrc != nullptr) 6 { 7 int nANSILen = WideCharToMultiByte(CodePage, 0, lpszSrc, -1, nullptr, 0, nullptr, nullptr); 8 char* pANSI = new char[nANSILen + 1]; 9 if (pANSI != nullptr) 10 { 11 ZeroMemory(pANSI, nANSILen + 1); 12 WideCharToMultiByte(CodePage, 0, lpszSrc, -1, pANSI, nANSILen, nullptr, nullptr); 13 return pANSI; 14 } 15 } 16 return nullptr; 17 } 18 /*=====================char*===>wchar_t*============================*/ 19 wchar_t* a2w(char* lpszSrc, UINT CodePage = CP_ACP) 20 { 21 if (lpszSrc != nullptr) 22 { 23 int nUnicodeLen = MultiByteToWideChar(CodePage, 0, lpszSrc, -1, nullptr, 0); 24 LPWSTR pUnicode = new WCHAR[nUnicodeLen + 1]; 25 if (pUnicode != nullptr) 26 { 27 ZeroMemory((void*)pUnicode, (nUnicodeLen + 1) * sizeof(WCHAR)); 28 MultiByteToWideChar(CodePage, 0, lpszSrc, -1, pUnicode, nUnicodeLen); 29 return pUnicode; 30 } 31 } 32 return nullptr; 33 } 34 35 36 ... ... 37 38 char* pcTemp1 = w2a(pcData7);//Unicode-->ANSI 39 printf("Unicode to ANSI: %d \n", (strlen(pcTemp1) + 1) * sizeof (CHAR));//4 40 wchar_t* pwcTemp2 = a2w(pcData2);//ANSI-->Unicode 41 printf("ANSI to Unicode: %d \n", (wcslen(pwcTemp2) + 1) * sizeof (WCHAR));//8 42 43 if (nullptr != pcTemp1) delete pcTemp1; 44 if (nullptr != pwcTemp2) delete pwcTemp2;
2. 方式2:使用 ATL的CW2A和CA2W 实现 #include "atlbase.h" #include "atlstr.h"
1 ATL::CW2A objW2A(pcData7);//Unicode-->ANSI 2 char* pcTemp3 = (char*)objW2A; 3 printf("ATL Unicode to ANSI: %d \n", (strlen(pcTemp3) + 1) * sizeof (CHAR));//4 4 5 ATL::CA2W objA2W(pcData2);//ANSI-->Unicode 6 wchar_t* pcTemp4 = (wchar_t*)objA2W; 7 printf("ATL ANSI to Unicode: %d \n", (wcslen(pcTemp4) + 1) * sizeof (WCHAR));//8
二. TCHAR*,std::string/std::wstring,CString的转换
- 场景:CString只限定在MFC里使用,但封装性能好;string 只要符合C++标准可以跨平台使用,移植性好,相比CString封装性差。
- 转换:
1. CString与TCHAR* 转换
1 //CString-->TCHAR* 2 CString strData1 = _T("abcdef"); 3 TCHAR* pcTemp5 = strData1.GetBuffer(); 4 //TCHAR*-->CString 5 TCHAR* pcData12 = _T("defgki"); 6 CString strTemp6(pcData12);
2. std::string与TCHAR* 转换
1 #if _UNICODE 2 //std::wstring-->wchar_t* 3 std::wstring strData3 = _T("defgki"); 4 const wchar_t* pcTemp8 = strData3.c_str(); 5 //wchar_t*-->std::wstring 6 const wchar_t* pcData14 = L"defgki"; 7 std::wstring strData5(pcData14); 8 #else 9 //std::string-->char* 10 std::string strData2 = "abcdef"; 11 const char* pcTemp7 = strData2.c_str(); 12 //char*-->std::string 13 const char* pcData13 = "abcdef"; 14 std::string strData4(pcData13); 15 #endif
3. std::string 与 CString 转换
1 #if _UNICODE 2 //CString-->std::wstring 3 CString strData6 = _T("abcdef"); 4 std::wstring strTemp9 = strData6.GetBuffer(); 5 //std::wstring-->CString 6 std::wstring strData7 = L"abcdef"; 7 CString strTemp10 = strData7.c_str(); 8 #else 9 //CString-->std::string 10 CString strData8 = _T("abcdef"); 11 std::string strTemp11 = strData8.GetBuffer(); 12 //std::string-->CString 13 std::string strData9 = L"abcdef"; 14 CString strTemp12 = strData9.c_str(); 15 #endif
- string:由https://www.cctry.com/的syc提供的封装相对较好的string_util(里面的课件讲的蛮好的,有时间可以学习下),不过只限定在windows环境使用,不能跨平台。
下载地址:https://files-cdn.cnblogs.com/files/blogs/666666/string_util.zip