What are TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR (etc.)?

Many C++ Windows programmers get confused over what bizarre identifiers like TCHARLPCTSTR are. Here, in brief, I would try to clear out the fog.
 
In general, a character can be 1 byte or 2 bytes. Let's say 1-byte character is ANSI, using which English characters are represented. And let's say 2-byte character is Unicode, which can represent ALL languages in the world. 
 
VC++ support char and wchar_t as native datatypes for ANSI and Unicode characters respectively.
 
What if you want your C/C++ program to be Character-mode independent? 
Use generic characters. That means, instead of replacing:
char cResponse; // 'Y' or 'N'
char sUsername[64];
// str* functions
with
wchar_t cResponse; // 'Y' or 'N'
wchar_t sUsername[64];
// wcs* functions
 
You can simply code it:
#include<TCHAR.H> // Implicit or explicit include
TCHAR cResponse; // 'Y' or 'N'
TCHAR sUsername[64];
// _tcs* functions
Thus, when your project is being compiled as Unicode, the TCHAR would translate to wchar_t. If it is being compiled as ANSI/MBCS, it would be translated to char. Likewise, instead of using strcpystrlenstrcat(including the secure versions suffixed with _s); or wcscpywcslenwcscat (including secure), you can simply use _tcscpy_tcslen_tcscat functions. 
 
When you need to express hard-coded string, you can use:
"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.
 
The non-prefixed string is ANSI string, the L prefixed string is Unicode, and string specified in _T or TEXTwould be either, depending on compilation.
 
String classes, like MFC/ATL's CString implement two versions using macro. There are two classes namedCStringA for ANSI, CStringW for Unicode. When you use CString (which is a macro/typedef), it translates to either of two classes.
Okay. The TCHAR type-definition was for a single character. You can definitely declare an array of TCHAR
What if you want to express a character-pointer, or a const-character-pointer - Which one of the following?
// 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;
After reading about TCHAR stuff, you'd definitely select the last one as your choice. But here is a better alternative. Before that, note that TCHAR.H header file declares only TCHAR datatype and for the following stuff, you need to include Windows.h (defined in WinNT.h).
 
NOTE: If your project implicitly or explicitly includes Windows.h, you need not include TCHAR.H
 
  • char* replacement: LPSTR
  • const char* replacement: LPCSTR
  • WCHAR* replacement: LPWSTR
  • const WCHAR* replacement: LPCWSTR (C before W, since const is before WCHAR)
  • TCHAR* replacement: LPTSTR
  • const TCHAR* replacement: LPCTSTR
Now, I hope you understand the following signatures What are TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR (etc.)? :
BOOL SetCurrentDirectory( LPCTSTR lpPathName );
DWORD GetCurrentDirectory(DWORD nBufferLength,LPTSTR lpBuffer);
Continuing. You must have seen some functions/methods asking you to pass number of characters, or returning the number of characters. Well, like GetCurrentDirectory, you need to pass number of characters, and notnumber of bytes. For example::
TCHAR sCurrentDir[255];
 
// Pass 255 and not 255*2 
GetCurrentDirectory(sCurrentDir, 255);
On the other side, if you need to allocate number or characters, you must allocate proper number of bytes. In C++, you can simply use new:
LPTSTR pBuffer; // TCHAR* 

pBuffer = new TCHAR[128]; // Allocates 128 or 256 BYTES, depending on compilation.
But if you use memory allocation functions like mallocLocalAllocGlobalAlloc, etc; you must specify the number of bytes!
pBuffer = (TCHAR*) malloc (128 * sizeof(TCHAR) );
Typecasting the return value is required, as you know. The expression in malloc's argument ensures that it allocates desired number of bytes - and makes up room for desired number of characters.
上一篇:CPU是如何解决冒险问题的?(下)


下一篇:用Modules管理环境变量