一、
使用函數_tcscpy_s:
CString theString( "This is a test" );
int
LPTSTR
_tcscpy_s(lpsz, sizeOfString, theString);
最後再轉換一下lpsz爲const型的
LPTSTR在UNICODE環境下編譯是wchar_t類型
二、
CString str = _T("Hello World!");
char szStr[256] = {0};
wcstombs(szStr, str, str.GetLength());
const char * p = szStr;
其實還可能出現其它類似的問題,如:
error C2664: “fopen”: 不能將參數 1 從“CString”轉換爲“const char *”
error C2039: “strcpy”: 不是“ATL::CStringT<BaseType,StringTraits>”的成員
但是程序在VC6下編譯得很好,經過研究發現是設置上有所不同。在VC6中,默認使用MBCS編碼,即多字節字符;而VC8、VC7默認的是Unicode編碼,所以...
關於這兩種編碼有何不同,我引用了網上的一篇文章,由於作者匿名,只能在此感謝:
http://pc.nengbang.cn/group_thread/view/id-2603
在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,裏面定義了一些宏用來幫助寫兩種編碼都兼容的代碼。
類型
一般文本
_TCHAR char char wchar_t
_TINT int int
_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(0sizeof()/szieof(TCHAR))就沒事了,呵呵
在Unicode下,一個中文字符就是一個字符,len = strlen() / 2;這樣可不行了
用VC6進行UNICODE編程
最近試圖將自己的程序編譯成Unicode版本,費了不少力氣,相關內容整理如下,適用於VC6,但VC7、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