TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR 之间的联系与区别

许多C++程序员在面对那些像TCHARLPCTSTR等奇怪的标示符时,很疑惑。这里,我将简要地介绍一些他们的来龙去脉。 


    一般来说,一个字符可以使12个字节。我们称1字节字符为ANSI,被用于英文字母的表示;称2字节字符为Unicode,可以用来表示世界上所有的语言。

    VC++中分别用charwchar_t作为表示ANSIUnicode原始字符类型。


    如果你想要保持你的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形式的话,TCHAR会被解释成char。同样的,可以将strcpy,strlen,strcat(包括他们加上_s的安全版本)和wcscpy,wcslen,wcscat(包括安全版本)都统一改写成_tcscpy,_tcslen,_tcscat函数。

     

    当你需要表示强编码的字符串是,你可以使用如下形式

"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.

    没有前缀的stringANSI的,加了L前缀的stringUnicode的,而加上了_T或者TEXT前缀的则根据编译器,可以是其中的任一种。

 

    String类们,就像MFC/ATL中的CString类一样通过宏来实现两种版本。分别是对于ANSICStringA和针对UnicodeCStringW。当你使用CString(他是一个宏或者转义类型)的时候,它能够被解释成任意一种。

    好的,TCHAR类型的定义是针对简单字符的。你当然可以声明一个TCHAR数组。


    如果你想表达一个字符指针或者一个常量字符指针,你该使用下面那一种方式呢?


// 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(定义在WinNT.h中)。
 
    注意:如果你的项目中包含了Windows.h,你不需要再包含TCHAR.H 

· char* 替代类型LPSTR

· const char* 替代类型LPCSTR

· WCHAR* 替代类型LPWSTR

· const WCHAR* 替代类型LPCWSTR 

CW前面,因为constWCHAR前面。)

· 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的参数设置确保了它能够分配给定数量的字节-使得对于给定数量的字符有足够的空间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值