TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR区别
来源:互联网 发布:重庆天畅软件 编辑:程序博客网 时间:2024/05/16 00:27
在C++的窗口应用程序开发过程中,我们经常对TCHAR,LPCTSTR这样的关键字迷惑。接下来将详细解释他们之间的区别。
通常,一个字符可以用1个字节或两个字节来表示。1个字节的字符为ANSI编码字符,通常所有的英文字符都采用ANSI编码。2个字节的字符为Unicode编码,可以表示世界上所有的语言。
在VC++编译器中,分别用char和wchar_t数据类型来标志ANSI和Unicode编码的字符。为了理解方便,我们可以认为两字节字符是Windows操作系统用例支持多语言的方法。Microsoft Windows用UTF-16字符编码来代表2字节编码。怎么样能让你的C/C++代码不依赖于具体的字符编码呢?
1. 用TCHAR代替char、wchar_t
例如:
2. VS工程设置
当你设置字符集为“使用Unicode字符集”时,宏_UNICODE就已经定义,这时候TCHAR代表wchar_t,当字符集设置为“使用多字节字符集”时,TCHAR代表char。
与此类似,为了让单个函数支持多种字符集或多种语言,应该使用特殊的函数(宏)。
可以使用_tcscpy,_tcslen,_tcscat函数代替strcpy, strlen, strcat(包括后缀为_s的函数)和wcscpy, wcslen, wcscat。
该宏定义在头文件TCHAR.h中。
可以简单地使用宏来定义,如下:
宏可以帮助我们很方便的使用ANSI或Unicode函数,为了方便,可以使用宏来定义SetWindowText函数:
你可以使用下面的方式来判断使用具体的字符集:
对于ANSI字符串没有前缀,对于Unicode字符集采用L前缀,使用前缀_T或TEXT可以根据编译器的设置来确定字符集,_T和TEXT都是宏,定义如下:
符号##是标记运算符,当字符串通过该宏传递参数进去可以将_T("Unicode") into L"Unicode",该标记符在C/C++中都存在。
但是不能使用该宏将一个变量(字符和字符串)转变成Unicode文本或non-Unicode文本。如下:
通常,一个字符可以用1个字节或两个字节来表示。1个字节的字符为ANSI编码字符,通常所有的英文字符都采用ANSI编码。2个字节的字符为Unicode编码,可以表示世界上所有的语言。
在VC++编译器中,分别用char和wchar_t数据类型来标志ANSI和Unicode编码的字符。为了理解方便,我们可以认为两字节字符是Windows操作系统用例支持多语言的方法。Microsoft Windows用UTF-16字符编码来代表2字节编码。怎么样能让你的C/C++代码不依赖于具体的字符编码呢?
1. 用TCHAR代替char、wchar_t
用一般的数据类型和名字代表字符和字符串
例如:
char cResponse; // 'Y' or 'N'char sUsername[64];用下面的方式来替代:wchar_t cResponse; // 'Y' or 'N'wchar_t sUsername[64];为了支持多语言(Unicode),可以用下面的方式:#include<TCHAR.H> // Implicit or explicit includeTCHAR cResponse; // 'Y' or 'N'TCHAR sUsername[64];//字符串
2. VS工程设置
在项目设置中,选择配置选项卡的常规,然后选择字符集。选择使用Unicode字符集。
设置好了以后,当你的项目用该字符集编译时,TCHAR会被翻译成wchar_t.当用ANSI/MBCS编译,则翻译成char。你可以通过项目设置很方便的使用char和wchar_t,不会受到关键字的影响。
3. TCHAR的定义如下:
#ifdef _UNICODEtypedef wchar_t TCHAR;#elsetypedef char TCHAR;#endif
当你设置字符集为“使用Unicode字符集”时,宏_UNICODE就已经定义,这时候TCHAR代表wchar_t,当字符集设置为“使用多字节字符集”时,TCHAR代表char。
与此类似,为了让单个函数支持多种字符集或多种语言,应该使用特殊的函数(宏)。
可以使用_tcscpy,_tcslen,_tcscat函数代替strcpy, strlen, strcat(包括后缀为_s的函数)和wcscpy, wcslen, wcscat。
//strlen的原型如下:size_t strlen(const char*);//wcslen的原型如下:size_t wcslen(const wchar_t* );//使用_tcslen的原型如下:size_t _tcslen(const TCHAR* );
4. WC是为宽字符而设计的,因此wcs表示宽字符串。_tcs表示_T字符集串。_T可能代表char或者wchar_t。但是实际上,_tcslen(或其他的_tcs开头的函数)并不是函数,它们是宏。他们的定义如下:
#ifdef _UNICODE#define _tcslen wcslen#else#define _tcslen strlen#endif
该宏定义在头文件TCHAR.h中。
5. 大家可能会问为什么它们定义成宏而不是函数?原因很简单,一个库或DLL可能导出与之相同的函数原型,忽略C++的重载。
如下,你可能会导出如下函数:
void _TPrintChar(char);//客户端怎么按意图调用它呢?void _TPrintChar(wchar_t);//_TPrintChar函数不能将该函数的参数变成2字节字符集,可能使用两个函数:void PrintCharA(char); // A = ANSIvoid PrintCharW(wchar_t);//W=wide character
可以简单地使用宏来定义,如下:
#ifdef _UNICODEvoid _TPrintChar(wchar_t);#elsevoid _TPrintChar(char);#endif//客户端可以简单的调用:TCHAR cChar;_TPrintChar(cChar);
宏可以帮助我们很方便的使用ANSI或Unicode函数,为了方便,可以使用宏来定义SetWindowText函数:
// WinUser.H#ifdef UNICODE#define SetWindowText SetWindowTextW#else#define SetWindowText SetWindowTextA#endif //!UNICODE
6. ANSI 和Unicode 字符串初始化
ANSI字符集,每个字符占一个字节。
Unicode:为了代表Unicode字符串,可以用前缀L,如下:
"This is ANSI String. Each letter takes 1 byte."L"This is Unicode string. Each letter would take 2 bytes, including spaces."在字符串前面的L表示把该字符串转换为Unicode字符串。转换后的字符串的源字符串长度的两倍。
你可以使用下面的方式来判断使用具体的字符集:
"ANSI String"; // ANSIL"Unicode String"; // Unicode_T("Either string, depending on compilation"); // ANSI or Unicode// or use TEXT macro, if you need more readability
对于ANSI字符串没有前缀,对于Unicode字符集采用L前缀,使用前缀_T或TEXT可以根据编译器的设置来确定字符集,_T和TEXT都是宏,定义如下:
// SIMPLIFIED#ifdef _UNICODE #define _T(c) L##c #define TEXT(c) L##c#else #define _T(c) c #define TEXT(c) c#endif
符号##是标记运算符,当字符串通过该宏传递参数进去可以将_T("Unicode") into L"Unicode",该标记符在C/C++中都存在。
但是不能使用该宏将一个变量(字符和字符串)转变成Unicode文本或non-Unicode文本。如下:
// SIMPLIFIED#ifdef _UNICODE #define _T(c) L##c #define TEXT(c) L##c#else #define _T(c) c #define TEXT(c) c#endif上面的代码将出现编译错误。_T(c)和_T(str)在ANSI编译模式下可以通过编译。
7. CString
MFC/ATL CString
通过宏也实现了2个版本
CStringA :ANSI
CStringW:Unicode
8. char 和 LPSTR
LP:代表长指针 C:代表常量 STR:代表字符串
- 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
9. 字符数和字节数
对于ANSI来说:字符数 = 字节数
对于Unicode来说:字符数 = 2 * 字节数
strlen, wcslen or _tcslen 返回的是字符数
sizeof( TCHAR ) 返回的是字节数
pBuffer = (TCHAR*) malloc (128 * sizeof(TCHAR) );
- TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR区别
- windows编程中的char, TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR区别
- TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR 之间的联系与区别
- TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR 之间的联系与区别
- What are TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR
- TCHAR,WCHAR,LPSTR,LPWSTR和LPCTSTR
- What are TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR
- TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR<一>
- TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR<二>
- TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR<三>
- TCHAR,WCHAR,LPSTR,LPWSTR和LPCTSTR
- TCHAR,WCHAR,LPSTR,LPWSTR,LPCSTR的区别
- What are TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR (etc.)?
- VC++中关于TCHAR,WCHAR,LPSTR,LPWSTR,LPCTSTR的解释
- What are TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR (etc.)?
- What are TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR (etc.)?
- What are TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR (etc.)?
- What are TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR (etc.)?
- UITableview cell上的数据或控件覆盖问题
- ABAP Function SELECT_OPTIONS_RESTRICT
- HTTP状态码
- Select statement doesn't use index.
- 一些非常实用的 Android 开发资源
- TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR区别
- 2013第十三周上机任务【教师兼干部】
- 又拍网架构中的分库设计
- drop user error ORA-00604 ORA-01418
- 九宫图
- vim map nmap
- 13_1理解基类中成员的访问限定符和派生类的继承方式
- What are TCHAR, WCHAR, LPSTR, LPWSTR, LPCTSTR (etc.)?
- 快速掌握一款新型的MCU