"const char *" 類型的實參與 "LPCTSTR" 類型的形參不兼容(即_T、TEXT("")和L"" 的問題)

基本概念
再解決問題以前要先弄懂一些概念。 
WIndows裏面有兩種字符編碼方式,分別爲ANSI和UNICODE編碼。數組

什麼是ANSI,什麼又是UNICODE呢?函數

ANSI字符集,它們正式的名稱應該是多字節字符系統(Multi-Byte Chactacter System,即MBCS)。Unicode碼也是一種國際標準編碼,採用二個字節編碼,與ANSI碼不兼容。 
ANSI (使用」「)中的字符采用8bit,而UNICODE (使用L」「)中的字符采用16bit。對於字符來講ANSI以單字節存放英文字符,以雙字節存放中文等字符,而Unicode,英文和中文的字符都以雙字節存放。 8bit的ANSI編碼只能表示256種字符,表示26個英文字母是綽綽有餘的,可是表示漢字,韓國語等有着成千上萬個字符的非西方字符確定就不夠了,正是如此才引入了UNICODE標準。 
那麼ANSI類型的字符和UNICODE類型的字符在Windows中如何定義,如何使用呢?編碼

定義使用 
由於Windows支持兩種字符串,這樣對應的就有了兩套字符串處理函數,好比:strlen和wcslen,分別用於處理兩種字符串.net

ANSI:即char,可用字符串處理函數:strcat(    ),strcpy(    ),    strlen(    )等 以str打頭的函數。   
UNICODE:即wchar_t 可用字符串處理函數:wcscat(),wcscpy(),wcslen()等 以wcs打頭的函數。 
1
2
補充: 
char :單字節變量類型,最多表示256個字符, 
wchar_t :寬字節變量類型(即:unsigned short類型),用於表示Unicode指針

Windows(MFC)中的實現
Windows既支持ANSI又支持UNICODE,在編寫代碼過程當中不可能在要求類型轉換的時候,從新改變字符串的類型,和使用於字符串上的操做函數。爲此, 標準C運行期庫和Windows 提供了宏定義的方式。code

在C語言裏面提供了 _UNICODE宏(有下劃線),在Windows裏面提供了UNICODE宏(無下劃線),只要定了_UNICODE宏和UNICODE宏,系統就會自動切換到UNICODE版本,不然,系統按照ANSI的方式進行編譯和運行。blog

即:
_UNICODE宏用於C運行期頭文件, 
UNICODE宏則用於Windows頭文件.
1
2
3
只定義了宏並不能實現自動的轉換,他還須要一系列的字符定義支持。爲了存儲這樣的通用字符,就有了TCHAR LPTSTR這樣一類通用類型。unicode

TCHAR字符串

若是定義了UNICODE宏則TCHAR被定義爲wchar_t。   
typedef    wchar_t    TCHAR;   
不然TCHAR被定義爲char   
typedef    char   TCHAR;   
1
2
3
4
2.LPTSTR編譯器

若是定義了UNICODE宏則LPTSTR被定義爲LPWSTR。
typedef    LPTSTR   LPWSTR;   
不然TCHAR被定義爲char   
typedef    LPTSTR   LPSTR;  
1
2
3
4
當沒有定義_UNICODE宏時,TCHAR = char,_tcslen =strlen 
當定義了_UNICODE宏時,TCHAR = wchar_t , _tcslen = wcslen

T是很是有意思的一個符號(TCHAR、LPCTSTR、LPTSTR、_T()、_TEXT()…),它表示使用一種中間類型,既不明確表示使用 MBCS,也不明確表示使用 UNICODE。那到底使用哪一種字符集?編譯的時候才決定

解決的方法
咱們通常用這幾個宏定義(_T、TEXT(「」)和L」」 )來解決字符串類型的轉換問題,那這幾個宏分別表明什麼含義呢? 
1. 在字符串前加一個L做用: 
如 L」個人字符串」 表示將ANSI字符串轉換成unicode的字符串,就是每一個字符佔用兩個字節。

strlen("asd")   =   3;   
strlen(L"asd")   =   6;
1
2
2. _T的做用 
_T宏能夠把一個引號引發來的字符串,根據你的環境設置,使得編譯器會根據編譯目標環境選擇合適的(Unicode仍是ANSI)字符處理方式 
若是你定義了UNICODE,那麼_T宏會把字符串前面加一個L。這時 _T(「ABCD」) 至關於 L」ABCD」 ,這是寬字符串。 
若是沒有定義,那麼_T宏不會在字符串前面加那個L,_T(「ABCD」) 就等價於 「ABCD」 
3._T _TEXT、TEXT使用說明 
咱們常常見這三個符號,那他們到底有啥區別呢?其實,_T、_TEXT、TEXT 三者效果相同 
Egg:

TCHAR   szStr1[]   =   TEXT("str1");   
char   szStr2[]   =   "str2";   
WCHAR   szStr3[]   =   L("str3");   
1
2
3
那麼第一句話在定義了UNICODE時會解釋爲第三句話,沒有定義時就等於第二句話。 
但二句話不管是否認義了UNICODE都是生成一個ANSI字符串,而第三句話老是生成UNICODE字符串。 
爲了程序的可移植性,建議都用第一種表示方法。 
但在某些狀況下,某個字符必須爲ANSI或UNICODE,那就用後兩種方法。

舉例說明
講了那麼多,相信小夥伴們已經知道了緣由,我就簡單的用一個例子說一下。以MessageBox()函數舉例,TextOut()也同樣。

int WINAPI MessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
1
LPCTSTR是一個不肯定的類型,因此咱們寫代碼的時候也能夠定義一個不肯定的類型 
Egg:

TCHAR szBuffer[10]=TEXT("str1") ; //靈活的定義數組 //LPTSTR szBuffer1 = new TCHAR[100];//靈活的定義指針 MessageBox(szBuffer, _TEXT("123"), MB_CANCELTRYCONTINUE);//這裏的LPCTSTR對應於_TEXT()這樣類型能夠任意轉換,無論是什麼類型的代碼都不會出錯   1 2 3 補充:VS2015 設置字符集的方法  項目設置:項目–屬性–配置屬性–常規–字符集–使用Unicode字符集/使用多字節字符集

相關文章
相關標籤/搜索