VC++中关于TCHAR,WCHAR,LPSTR,LPWSTR,LPCTSTR的解释

Wesley13
• 阅读 859

一般来说,一个字符(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的参数中,确定了分配字节的大小,并在内存中开辟相应的空间。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这