【轉】 今天寫的一段代碼涉及到MBCS編碼和UNICODE編碼的相互轉換,查了一下MSDN的相關資料,整理以下: 在VC6中,默認使用MBCS編碼,即多字節字符,實際就是支持大於0x80的ASCII碼。這樣,一箇中文字能夠表示爲2個字節,GB2312就是這樣表示的。 VC6的默認安裝是不帶UNICODE庫的,要在VC6中寫UNICODE程序,必須安裝CRT和MFC的Unicode庫。 要使你的程序支持Unicode,要在你的項目屬性中去掉"_MBCS"宏定義,增長"UNICODE"和"_UNICODE"兩個宏定義。(注意,這兩個都應該加上,由於CRT和MFC使用UNICODE定義,而STL則使用_UNICODE) 若是你的程序是MFC的,則Unicode版MFC庫的入口點是wWinMainCRTStartup。 爲了方便開發者,VC6中提供了Tchar.h,裏面定義了一些宏用來幫助寫兩種編碼都兼容的代碼。 類型 通常文本 數據類型名稱 _UNICODE 和 _MBCS 未定義 _MBCS 已定義 _UNICODE 已定義 _TCHAR char char wchar_t _TINT int int wint_t _TSCHAR signed char signed char wchar_t _TUCHAR unsigned char unsigned char wchar_t _TXCHAR char unsigned char wchar_t _T 或 _TEXT 無效(由預處理器移除) 無效(由預處理器移除) L(將後面的字符或字符串轉換成相應的 Unicode 形式) CRT中的相關函數在Tchar.h中都定義了相應的替代,基本是將str換成了_tcs,好比:CRT中的unsigned int strlen(const char *)如今是unsigned int _tcslen(const TCHAR*),在Uniocde時,將被替換爲unsigned int _wcslen(const wchar_t)*,而在MBCS時,會被替換爲unsigned int _mcslen(const char*)。 看,寫Unicode和MBCS兼容的代碼挺容易的吧,我總結了一些替換規則 1 將char換成TCHAR (unsigned char必須去掉unsigned) 2 將str函數換成_tcs函數 3 將字符串常量定義加要_T("")宏 4 printf函數族必須修改成wprintf,不過要注意千萬不要使用wprintf函數來解析char型 不少時候程序中既須要Unicode,又須要使用ASCII,這時須要用到操做系統的2個API WideCharToMultiByte用來將Unicode字符串轉化爲MBCS的 MultiByteToWideChar用來將MBCS字符串轉化爲Unicode的 一些注意事項: 在Unicode編碼下,sizeof沒那麼可靠了,memset( ,0, sizeof())的習慣用法可能會出大錯,改爲memset(,0,sizeof()/szieof(TCHAR))就沒事了,呵呵 在Unicode下,一箇中文字符就是一個字符,len = strlen() / 2;這樣可不行了 用VC6進行UNICODE編程 最近試圖將本身的程序編譯成Unicode版本,費了很多力氣,相關內容整理以下,適用於VC6,但VC七、VC8應該也差很少的(後者新建項目缺省即按Unicode編譯)。 1. 添加 UNICODE 和 _UNICODE 預處理定義 位置:Project Settings -> C/C++ -> Preprocessor definitions 添加了這兩個定義後,MFC的一些內置類型如 TCHAR、CString 都將轉爲支持寬字符類型(wchar_t) 2. 使用寬字符相關類型,如: char -> TCHAR、char * -> LPTSTR、const char * -> LPCTSTR 3. 對字符串常量使用 _T() 宏 4. 替換C庫中的中字符串操做函數,如 strlen -> _tcslen、strcmp -> _tcscmp 等 相似的還有C庫中字符串與數字的轉換函數,如 atoi -> _ttoi、itoa -> _itot 等 5. 將 Project Settings -> Link -> Output -> Entry Point 設爲 wWinMainCRTSTartup 不然會有以下錯誤: msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16 6. C++標準庫中的string,有對應的寬字符版本wstring,二者均爲basic_string的特化版本 可在StdAfx.h中: #ifdef _UNICODE #define tstring wstring #else #define tstring string #endif 而後在代碼中使用 tstring 便可,相似的還有 fstream/wfstream、ofstream/wofstream 等 7. 寬字符版本的英文字符仍可直接與整型值進行比較,如: CString s = _T("ABC"); ASSERT(s[0] == 'A'); 8. 對於仍需使用ANSI字符串的地方,如第三方類庫的接口,仍可繼續使用;如需進行Unicode字符串和ANSI字符串的互轉換,可以使用 MultiByteToWideChar 和 WideCharToMultiByte編程