免責申明(必讀!):本博客提供的所有教程的翻譯原稿均來自於互聯網,僅供學習交流之用,切勿進行商業傳播。同時,轉載時不要移除本申明。如產生任何糾紛,均與本博客所有人、發表該翻譯稿之人無任何關系。謝謝合作!
原文鏈接:http://www.codeproject.com/Articles/76252/What-are-TCHAR-WCHAR-LPSTR-LPWSTR-LPCTSTR-etc
許多VC++ 程序員對於像TCHAR,LPCTSTR這樣詭異的標識符感到非常迷惑,今天,我將嘗試簡短的把這團迷霧解釋清楚。
一般來說,一個字符(character)占用1字節或是2字節,我們說1字節的字符是ANSI,他可以用來表示英語字母,而2字節的我們稱之為Unicode,可以表示世界上所有的語言。。
VC++使用char和wchar_t的內置數據類型來分別作為表示ANSI和Unicode字符。
如果你想讓你的C/C++程序是字符集無關的,該怎么做呢?
如果你用通常的字符集來寫,你可能會寫成這樣的。
char cResponse; // 'Y' or 'N'
char sUsername[64];
// str* functions
和這樣的
wchar_t cResponse; // 'Y' or 'N'
wchar_t sUsername[64];
// wcs* functions
而現在,你可以簡單的這樣寫。
#include<TCHAR.H> // Implicit or explicit include
TCHAR cResponse; // 'Y' or 'N'
TCHAR sUsername[64];
// _tcs* functions
從此,當你的項目被作為Unicode編譯的時候,TCHAR將會被轉換成wchar_t,如果是被作為ANSI/MBCS來編譯,則會自動轉換成char,
同樣的,比起使用strcpy
, strlen
, strcat(也包含以_s結尾的安全版本)或者
wcscpy
, wcslen
,wcscat(安全版本也可),你可以簡單的使用
_tcscpy
,_tcslen
, _tcscat 這些函數。
當你表示硬編碼的string時,你可以使用
"ANSI String"; // ANSI
L"Unicode String"; // Unicode
_T("Either string, depending on compilation"); // ANSI or Unicode
// or use TEXT macro, if you need more readability.
沒有前綴的string是ANSI string,有L前綴的是Unicode,而又_T或者TEXT指定的string則二者皆可,取決於編譯器。
String類,像MFC/ATL的CString類使用宏實現了兩個版本,CStringA是ANSI,CStringW是為Unicode,當你使用CString(一個宏/typedef)的時候,會被自動轉換成兩個類中的一個
ok,TCHAR是一個單字符,你就可以清晰的定義一個TCHAR數組,當你想表示一個字符指針或const字符指針的時候,你會使用下面三個中的哪個呢?
// ANSI characters
foo_ansi(char*);
foo_ansi(const char*);
/*const*/ char* pString;
// Unicode/wide-string
foo_uni(WCHAR*); // or wchar_t*
foo_uni(const WCHAR*);
/*const*/ WCHAR* pString;
// Independent
foo_char(TCHAR*);
foo_char(const TCHAR*);
/*const*/ TCHAR* pString;
當讀完一些關於TCHAR的內容的時候,你應該會選擇一個正確的,但是,事實上,還有更好的選擇,在那之前,注意TCHAR.H頭文件僅僅生命了TCHAR類型,而為了使用下面的類型,你需要
吧Windows.h包含進去。
注意:如果你的項目已經隱式或是顯式地包含了Windows.h那就不必包含了。
- char* 替換:
LPSTR
- const char* 替換:
LPCSTR
- WCHAR* 替換:
LPWSTR
- const WCHAR* 替換:
LPCWSTR
(C在W之前, 因為const
在WCHAR之前
) - TCHAR* 替換:
LPTSTR
- const TCHAR* 替換:
LPCTSTR
現在,希望你可以理解下面的函數原型
BOOL SetCurrentDirectory( LPCTSTR lpPathName );
DWORD GetCurrentDirectory(DWORD nBufferLength,LPTSTR lpBuffer);
繼續,你一定見過一些函數/方法讓你傳遞字符集的大小,或者返回它的大小,比如GetCurrentDirectory函數,需要傳遞字符的數目而不是字節的數目舉個例子
TCHAR sCurrentDir[255];
// Pass 255 and not 255*2
GetCurrentDirectory(sCurrentDir, 255);
另一方面,如果你需要分配字符的數目,你比如分配適當大小的字節,在C++中,你可以簡單的使用new方法:
LPTSTR pBuffer; // TCHAR*
pBuffer = new TCHAR[128]; // Allocates 128 or 256 BYTES, depending on compilation.
但是,你如果你使用內存分配函數像malloc
,LocalAlloc
, GlobalAlloc
, 等,你必須指定字節數。
pBuffer = (TCHAR*) malloc (128 * sizeof(TCHAR) );
對返回值進行一次類型轉換是必需的,如你所知,在malloc的參數中,確定了分配字節的大小,並在內存中開辟相應的空間。
著作權聲明:本文由http://www.cnblogs.com/lazycoding翻譯,歡迎轉載分享。請尊重作者勞動,轉載時保留該聲明和作者博客鏈接,謝謝!