【原譯】什么是TCHAR,WCHAR,LPSTR,LPWSTR,LPCTSTR.等等


免責申明(必讀!):本博客提供的所有教程的翻譯原稿均來自於互聯網,僅供學習交流之用,切勿進行商業傳播。同時,轉載時不要移除本申明。如產生任何糾紛,均與本博客所有人、發表該翻譯稿之人無任何關系。謝謝合作!

原文鏈接: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,

同樣的,比起使用strcpystrlenstrcat(也包含以_s結尾的安全版本)或者wcscpywcslen,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 (CW之前, 因為 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,LocalAllocGlobalAlloc, 等,你必須指定字節數。

pBuffer = (TCHAR*) malloc (128 * sizeof(TCHAR) );

對返回值進行一次類型轉換是必需的,如你所知,在malloc的參數中,確定了分配字節的大小,並在內存中開辟相應的空間。


著作權聲明:本文由http://www.cnblogs.com/lazycoding翻譯,歡迎轉載分享。請尊重作者勞動,轉載時保留該聲明和作者博客鏈接,謝謝!







免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM