设为首页 加入收藏

TOP

ANSI与Unicode编码,TCHAR | LPSTR | LPCSTR | LPWSTR | LPCWSTR | LPTSTR | LPCTSTR 的含义(一)
2017-10-13 09:44:19 】 浏览:9151
Tags:ANSI Unicode 编码 TCHAR LPSTR LPCSTR LPWSTR LPCWSTR LPTSTR LPCTSTR 含义

一个字符可以用1-byte表示,即ANSI编码;

一个字符也可用2-bytes表示,即Unicode编码(Unicode其实还包含了更多内容,不止2-bytes)。

Visual C++支持char和wchar_t作为ANSI和Unicode的原始数据类型。

例如

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

 

TCHAR则是根据选择的字符集决定是翻译成char还是wchar_t,字符集的设置如下:

所以TCHAR的定义如下:

#ifdef _UNICODE
typedef wchar_t TCHAR;
#else
typedef char TCHAR;
#endif

 

在windows中,一般前缀 T 代表了它可以自适应不同的字符集。

比如:strcpystrlenstrcat(包括安全后缀_s)代表ANSI版本;

         wcscpywcslenwcscat(包括安全后缀_s),代表Unicode版本,这里WC代表Wide Character;

         _tcscpy_tcslen_tcscat则视情况而定:

size_t strlen(const char*); //ANSI
size_t wcslen(const wchar_t* ); //Unicdoe
size_t _tcslen(const TCHAR* ); //ANSI or Unicode

 


 我们知道一个string使用双引号表示,这种表示说明它是一个ANSI-string,每个字符占1-byte,例如:

"This is ANSI String. Each letter takes 1 byte."

要转换成Unicdeo-string需要加前缀:L

[__strong__]L"This is Unicode string. Each letter would take 2 bytes, including spaces."

 

Unicode编码的字符,每个都占用2-bytes,哪怕是可以用1-byte表示的,比如英文字母,数字,null字符等。所以一个unicode-string占用的字节总是2-bytes的倍数。

结合上面提到的 T 前缀,一种适用于两种字符集的写法是这样的:

"ANSI String"; // ANSI
L"Unicode String"; // Unicode

_T("Either string, depending on compilation"); // ANSI or Unicode

 

_TTEXT是一个宏定义,它与前缀 T 表示的意思一样,定义如下:

// SIMPLIFIED
#ifdef _UNICODE 
 #define _T(c) L##c
 #define TEXT(c) L##c
#else 
 #define _T(c) c
 #define TEXT(c) c
#endif

上面的##叫“token-pasting operator”。在Unicode下,_T("Unicode")被翻译成 L"Unicode";在ANSI下,_T("Unicode")被翻译成 “Unicode”

 

注意,不能通过_T来转换一个变量(string or character),下面的操作是不允许的:

char c = 'C';
char str[16] = "CodeProject";

_T(c);
_T(str);

如果你是在ANSI(Multi-Byte)下编译,可以顺利通过,_T(c), _T(str)被翻译成c, str;

但是在Unicode下编译,就会报错:

error C2065: 'Lc' : undeclared identifier
error C2065: 'Lstr' : undeclared identifier

结合_T的定义不难弄懂。

 

在windows中,几乎所有需要传入string或character的API,都有通用的版本,例如: SetWindowTextA/W,就可以统一写成:

BOOL SetWindowText(HWND, const TCHAR*);

但我们知道SetWindowText是一个宏,它代表了以下两种之一:

BOOL SetWindowTextA(HWND, const char*);
BOOL SetWindowTextW(HWND, const wchar_t*);

但其实,在内部实现时,不论ANSI还是Unicode都统一通过Unicode方式实现,当你调用 SetWindowTextA 时(传入ANSI-string),它会先转化成Unicode-string,再调用 SetWindowTextW实现。真正发挥作用的只有Unicode的版本!

所以在写代码时建议是直接调用Unicode版本的api,尽管我们对ANSI版本的string更熟悉。

Note:存在另外一个typedef:WCHAR,它等价于wchar_t

 


 我们知道strlen定义如下:

size_t strlen(const char*);

它也可以写成

size_t strlen(LPCSTR);

所以

// Simplified
typedef const char* LPCSTR;  

它的含义如下

  • LP: Long Pointer
  • C: Constant
  • STR: String

Long Pointer与Pointer意思一样。

 

举一反三,对于Unicode字符,我们有:

size_t wcslen(const wchar_t* szString); // Or WCHAR*
size_t wcslen(LPCWSTR szString);

这里 LPCWSTR代表

typedef const WCHAR* LPCWSTR;

它的含义如下

  • LP - Pointer
  • C - Constant
  • WSTR - Wide character String

更进一步,有LPCTSTR

  • LP - Pointer
  • C - Constant
  • T = TCHAR
  • STR = String

总结:

  • TCHAR - char / wchar_t (取决于字符集)
  • LPSTR - char*
  • LPCSTR - const char*
  • LPWSTR - wchar_
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇读书笔记 effective c++ Item 47 .. 下一篇城市公交网建设问题

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目