您的位置:首页 > 其它

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

2013-05-13 15:25 561 查看


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

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

一般来说,一个字符可以使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形式的话,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.

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

String类们,就像MFC/ATL中的CString类一样通过宏来实现两种版本。分别是对于ANSI的CStringA和针对Unicode的CStringW。当你使用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

(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的参数设置确保了它能够分配给定数量的字节-使得对于给定数量的字符有足够的空间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: