您的位置:首页 > 其它

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

2012-03-12 17:18 531 查看
Many C++ Windows programmers get confused over what bizarre identifiers like 
TCHAR
LPCTSTR
 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:


 Collapse | Copy
Code
char cResponse; // 'Y' or 'N'
char sUsername[64];
// str* functions

with


 Collapse | Copy
Code
wchar_t cResponse; // 'Y' or 'N'
wchar_t sUsername[64];
// wcs* functions

 
You can simply code it:


 Collapse | Copy
Code
#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 
strcpy
strlen
strcat
(including
the secure versions suffixed with _s); or 
wcscpy
wcslen
wcscat
 (including
secure), you can simply use 
_tcscpy
_tcslen
_tcscat
 functions. 
 
When you need to express hard-coded 
string
,
you can use:


 Collapse | Copy
Code
"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 
TEXT
would
be either, depending on compilation.
 
String
 classes, like MFC/ATL's 
CString
 implement
two versions using macro. There are two classes named
CStringA
 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?


 Collapse | Copy
Code
// 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 

 :


 Collapse | Copy
Code
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::


 Collapse | Copy
Code
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
:


 Collapse | Copy
Code
LPTSTR pBuffer; // TCHAR*

pBuffer = new TCHAR[128]; // Allocates 128 or 256 BYTES, depending on compilation.

But if you use memory allocation functions like 
malloc
LocalAlloc
GlobalAlloc
,
etc; you must specify the number of bytes!


 Collapse | Copy
Code
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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息