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.
相关文章
|
存储 数据挖掘 Windows
服务器数据恢复-zfs文件系统服务器raidz数据恢复案例
服务器数据恢复环境: 一台服务器共配备32块硬盘,组建了4组RAIDZ,Windows操作系统+zfs文件系统。 服务器故障: 服务器在运行过程中突然崩溃,经过初步检测检测没有发现服务器存在物理故障,重启服务器后故障依旧,需要恢复服务器内的大量数据。
服务器数据恢复-zfs文件系统服务器raidz数据恢复案例
|
安全 网络安全 网络虚拟化
华为ensp模拟器实现通信安全(交换机配置vlan)
华为ensp模拟器,实现vlan隔离,将不同的交换机接口放入不同的vlan步骤以及实现原理, 交换机的access接口与trunk接口的功能以及实现步骤
1166 0
华为ensp模拟器实现通信安全(交换机配置vlan)
|
5月前
|
存储 固态存储 IDE
移动硬盘盒,机械硬盘和固态硬盘通用吗?
移动硬盘盒能否同时支持机械硬盘(HDD)和固态硬盘(SSD)?本文详解硬盘盒的兼容性问题,涵盖接口类型(如SATA、NVMe)、尺寸规格(2.5英寸、3.5英寸、M.2)及使用体验差异,助你正确选择适配的硬盘盒,确保兼容与性能兼顾。
|
10月前
|
存储 前端开发 安全
如何在自己的网站接入API接口获取数据?分步指南与实战示例
将第三方API(如微店API)接入网站是扩展功能和获取实时数据的关键。流程包括注册开发者账号、申请API权限、设置认证机制(OAuth 2.0或AppKey签名)、调用API实现前后端协作、处理数据与错误、优化安全性能,并解决常见问题。确保遵循最佳实践,保障系统稳定与安全。通过这些步骤,开发者可高效整合数据,提升应用功能。
|
机器学习/深度学习 人工智能 自然语言处理
|
机器学习/深度学习
|
存储 关系型数据库 MySQL
MySQL性能优化指南
【10月更文挑战第16天】MySQL性能优化指南
1116 0
|
存储 Linux Docker
在Docker中,如何更改Docker的默认存储设置?
在Docker中,如何更改Docker的默认存储设置?
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp的毕业设计选题系统的详细设计和实现(源码+lw+部署文档+讲解等)
基于SpringBoot+Vue+uniapp的毕业设计选题系统的详细设计和实现(源码+lw+部署文档+讲解等)
273 0
|
前端开发 UED
🌟前端分页加载/懒加载预览PDF🌟
🌟前端分页加载/懒加载预览PDF🌟