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

简介: Many C++ Windows programmers get confused over what bizarre identifiers like TCHAR, LPCTSTR are.
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:
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  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:
"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?
// 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  Cool | :cool:  :
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  not number 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  malloc LocalAlloc GlobalAlloc , 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.
相关文章
|
9月前
|
编译器 C语言
你应该知道的C语言干货(5)(memset,memcpy,memmove,memcmp)
我们知道包含string.h头文件后,就可以使用memset,memcpy,memmove,memcmp这些库函数,接下来让我们了解他们。
49 0
|
11月前
|
存储 编译器 API
【为什么】_stprintf_s,TCHAR,_T
【为什么】_stprintf_s,TCHAR,_T
wchar_t转为char*
wchar_t转为char*
64 0
char、signed char和unsigned char
char、signed char和unsigned char
221 0
char*转为LPCWSTR
char*转为LPCWSTR
74 0
|
Windows
wchar、char、CString、string
wchar、char、CString、string
107 0