Unicode编程
1.Windows定義的Unicode數據類型有哪些?
數據類型 說明
WCHAR Unicode字符(源自系統宏定義typedef wchar_t WCHAR;)
PWSTR 指向Unicode字符串的指針
PCWSTR 指向一個恒定的Unicode字符串的指針
對應的ANSI數據類型為CHAR,LPSTR和LPCSTR。
(LPCTSTR和const TCHAR*是完全等同的。其中L表示long指針,P(pointer)表示這是一個指針;C(const)表示是一個常量;T(_T宏)表示兼容ANSI和Unicode,STR(string)表示這個變量是一個字符串)
Win32 API在winnt.h頭文件中定義了一些實現字符和常量字符串的宏進行ANSI/Unicode通用編程。
ANSI/Unicode通用數據類型為TCHAR,PTSTR,LPCTSTR。
#ifdefUNICODE // 注意此處沒有沒有下劃線
typedef WCHAR???????? TCHAR, *PTCHAR;
typedef LPWSTR??????? LPTCH, PTCH;
typedef LPWSTR??????? PTSTR, LPTSTR;
typedef LPCWSTR?????? LPCTSTR;
#define __TEXT(quote) L##quote??????? // r_winnt
?
#else??????????????????????? // r_winnt
??????? typedef char????????? TCHAR, *PTCHAR;
??????? typedef LPSTR???????? LPTCH, PTCH;
??????? typedef LPSTR???????? PTSTR, LPTSTR;
??????? typedef LPCSTR??????? LPCTSTR;
??????? #define __TEXT(quote) quote?????????? // r_winnt
#endif??????????????????????// r_winnt
2.如何編寫Unicode源代碼?
只需要定義兩個宏(UNICODE和 _UNICODE),就可以修改然后重新編譯該源文件。
_UNICODE宏用于C運行期頭文件,而UNICODE宏則用于Windows頭文件。當編譯源代碼模塊時,通常必須同時定義這兩個宏。
3.如何對Unicode進行操作?
? 1. ANSI操作函數:??????????以str開頭,如strcpy(),strcat(),strlen();
??? 2. Unicode操作函數:??????以wcs開頭,如wcscpy,wcscpy(),wcslen();
??? 3. ANSI/Unicode操作函數: 以_tcs開頭 _tcscpy(C運行期庫);
??? 4. ANSI/Unicode操作函數: 以lstr開頭 lstrcpy(Windows函數);
考慮ANSI和Unicode的兼容,我們需要使用以_tcs開頭或lstr開頭的通用字符串操作函數。
所有新的和未過時的函數在Windows2000中都同時擁有ANSI和Unicode兩個版本。ANSI版本函數結尾以A表示;Unicode版本函數結尾以W表示。Windows會如下定義:
#ifdef UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowExA
#endif // !UNICODE
注意:使用函數strlen和wcslen都是獲得的字符串的長度,使用sizeof()可獲得耗用內存空間
4.如何表示Unicode字符串常量?
字符集 實例
ANSI “string”
Unicode L“string”
ANSI/Unicode T(“string”)或_TEXT(“string”)if( szError[0] == _TEXT(‘J’) ){ }
5.如何編寫符合ANSI和Unicode的應用程序?
(1)將文本串視為字符數組,而不是chars數組或字節數組。
(2)將通用數據類型(如TCHAR和PTSTR)用于文本字符和字符串。
(3)將顯式數據類型(如BYTE和PBYTE)用于字節、字節指針和數據緩存。
(4)將TEXT宏用于原義字符和字符串。
(5)執行全局性替換(例如用PTSTR替換PSTR)。
6.如何判斷一個文本文件是ANSI還是Unicode?
判斷如果文本文件的開頭兩個字節是0xFF和0xFE,那幺就是Unicode,否則是ANSI。
7.如何在Unicode與ANSI之間轉換字符串?
Windows函數MultiByteToWideChar用于將多字節字符串轉換成寬字符串;函數WideCharToMultiByte將寬字符串轉換成等價的多字節字符串。
另外兩個常用的函數(如果出現轉換漢文的話請使用setlocale(LC_ALL, "chs");):
size_t mbstowcs( wchar_t *wcstr, const char *mbstr, size_tcount);
size_t wcstombs( char * mbstr, const wchar_t *wcstr, size_tcount);示例程序:
voidC對話框測試Dlg::OnBnClickedButton1()
{
???? // TODO: 在此添加控件通知處理程序代碼
?
???? DWORD?? dwNum = 0;
???? wchar_t wText[7]? = L"寬字符串示例";//L告示編譯器使用兩個字節的 unicode字符集
???? char??? sText[13] =?"窄字符串示例";
?
???? wchar_t *pwText =NULL;//指向有ASCII轉向UNICODE生成的寬字節
???? char??? *psText =NULL;//指向有UNICODE轉向ASCII生成的窄字節
???? // 轉換一下
???? dwNum = MultiByteToWideChar(CP_ACP,0,sText,-1,NULL,0);
???? pwText = new wchar_t[dwNum];
???? if (!pwText)
???? {
???????? delete[] pwText;
???? }
???? MultiByteToWideChar(CP_ACP,// ANSI code page
???????? 0,?????//
???????? sText,? // MBCS字符串
???????? -1,????//返回UNICODE字符串包括'\0'的長度
???????? pwText, // UNICODE字符串數組
???????? dwNum); // UNICODE字符串數組元素個數
???? ::MessageBoxW(this->m_hWnd,pwText,L"顯示窄轉寬字符串",MB_OK);
???? delete[] pwText;
?
???? dwNum = WideCharToMultiByte(CP_OEMCP,0,wText,-1,NULL,0,NULL,FALSE);
???? psText = new char[dwNum];
???? if (!psText)
???? {
???????? delete[] psText;
???? }
???? WideCharToMultiByte (CP_OEMCP,0,wText, -1,psText,dwNum,NULL,FALSE);
???? ::MessageBoxA(this->m_hWnd,psText,"顯示寬轉窄字符串",MB_OK);
???? delete[] psText;
}
?
?
8.默認環境
???????? 在VC6中,默認使用MBCS編碼,即多字節字符;而VC8、VC7默認的是Unicode編碼,實際就是支持大于0x80的ASCII碼。這樣,一個中文字可以表示為2個字節,GB2312就是這樣表示的。
???????? 檢測環境的代碼:
#ifndefUNICODE
??? AfxMessageBox(TEXT("ASCII"));
#else
??? AfxMessageBox(TEXT("UNICODE"));
#endif
?9.其他知識點
字符串前面加L表示該字符串是Unicode字符串。
_T是一個宏,如果項目使用了Unicode字符集(定義了UNICODE宏),則自動在字符串前面加上L,否則字符串不變。因此,Visual C++里邊定義字符串的時候,用_T來保證兼容性。VC支持ascii和unicode兩種字符類型,用_T可以保證從ascii編碼類型轉換到unicode編碼類型的時候,程序不需要修改。
?
總結
- 上一篇: 互斥体CMutex的使用
- 下一篇: 几个预编译指令的用法