【原译】什么是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,
同样的,比起使用strcpy
, strlen
, strcat(也包含以_s结尾的安全版本)或者
wcscpy
, wcslen
,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
(C在W之前, 因为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
,LocalAlloc
, GlobalAlloc
, 等,你必须指定字节数。
pBuffer = (TCHAR*) malloc (128 * sizeof(TCHAR) );
对返回值进行一次类型转换是必需的,如你所知,在malloc的参数中,确定了分配字节的大小,并在内存中开辟相应的空间。
著作权声明:本文由http://www.cnblogs.com/lazycoding翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述