摘要:
本文总结对比了ANSI/Unicode,char/wchar_t,LPSTR/LPWSTR。
简单描述了char, wchar_t, TCHAR的初始化,操作函数,输出的方法。
数据类型 | 操作 | 初始化 | 输出 | WinLP | |
ANSI | char | str(strcpy) | "char" | printf | LPSTR |
Unicode | wchar_t | wcs(wcscpy) | L"char" | wprintf | LPWSTR |
通用 | TCHAR | _tcs(_tcscpy) | _T("char") | _tprintf |
1. ANSI和Unicode
ANSI :单字节表示字符(8位),主要是拉丁语系
Unicode:双字节表示字符(16位),汉语等
(1) 可以很容易地在不同语言之间进行数据交换。
(2) 使你能够分配支持所有语言的单个二进制.exe文件或DLL文件。
(3) 提高应用程序的运行效率。
2. char 和 wchar_t
ANSI "char";
UNICODE L"char";
ANSI/UNICODE_T("char") or _TEXT("char");
3. WinLP
LP:代表长指针 C:代表常量 STR:代表字符串
-
char* replacement:
LPSTR
-
const char* replacement:
LPCSTR
-
WCHAR* replacement:
LPWSTR
-
const WCHAR* replacement:
LPCWSTR
(C before W,sinceconst
is beforeWCHAR
) -
TCHAR* replacement:
LPTSTR
-
const TCHAR* replacement:
LPCTSTR
-
// #include <winnt.h> typedef CHAR char; typedef WCHAR wchar_t; #ifdef UNICODE // r_winnt typedef WCHAR TCHAR, *PTCHAR; typedef WCHAR *LPWSTR; typedef LPWSTR LPTSTR; typedef CONST WCHAR *LPCWSTR; typedef LPCWSTR LPCTSTR; #define __TEXT(quote) L##quote // r_winnt #else /* UNICODE */ // r_winnt typedef CHAR TCHAR, *PTCHAR; typedef CHAR *LPSTR; typedef LPSTR LPTSTR; typedef CONST CHAR *LPCSTR, typedef LPCSTR LPCTSTR; #define __TEXT(quote) quote #endif /* UNICODE */ // r_winnt #define TEXT(quote) __TEXT(quote) // r_winnt
4. 操作
双字节(DBCS)字符集中,字符串的每个字符可以包含一个或两个字节。如果只是调用strlen()函数,那么你就无法知道字符串到底有多少个字符,它只能告诉你到达结尾的0之前有多少个字节。
标准c中的strcpy,strchr,strcat等只能用于ANSI字符串,不能正确处理UNICODE字符串,因此也提供了一组补充函数,功能等价,但用于UNICODE码。我们来看看string .h字符串头文件中是怎样处理char*和wchar_t*两个字符串版本的:
// …/Microsoft Visual Studio 8/VC/include/string.h
char *strcat(char*,constchar*);
wchar_t *wcschr(wchar_t*,constwchar_t*);
strlen/wcslen、strcpy/wcscpy、strncpy/wcsncpy、strcat/wcscat、strncat/wcsncat、strcmp/wcscmp、strncmp/wcsncmp、strchr/wcschr、strrchr/wcsrchr、strstr/wcsstr、sprintf/swprintf、strtol/wcstol、strtoul/wcstoul;
类似的还有strchr/wcschr,strcmp/wcscmp,strlen/wcslen etc. ANSI 操作函数以str开头 strcpy ,UNICODE 操作函数以wcs开头 wcscpy。
MBCS 操作函数以_mbs开头 _mbscpy
ANSI/UNICODE 操作函数以_tcs开头 _tcscpy(C运行期库)
lstr开头 lstrcpy(Windows API-KERNEL32.DLL)
lstrlen(lstrlenA/lstrlenW)、lstrcpy(lstrcpyA/lstrcpyW)、lstrcpyn(lstrcpynA/lstrcpynW)、lstrcat(lstrcatA/lstrcatW)、lstrcmp(lstrcmpA/lstrcmpW)、lstrcmpi(lstrcmpiA/lstrcmpiW)
WINBASEAPI LPSTR WINAPI lstrcpyA( __out LPSTR lpString1, __in LPCSTR lpString2 ); WINBASEAPI LPWSTR WINAPI lstrcpyW( __out LPWSTR lpString1, __in LPCWSTR lpString2 ); #ifdef UNICODE #define lstrcpy lstrcpyW #else #define lstrcpy lstrcpyA #endif // !UNICODE
所有新的和未过时的函数在Windows2000中都同时拥有ANSI和UNICODE两个版本。ANSI版本函数结尾以A表示;UNICODE版本函数结尾以W表示。操作系统根据是否定义了UNICODE宏来调用合适版本的API。
5. 初始化
ANSI: char *str = "char"; UNICODE : wchar_t* wstr = L"char"; ANSI/UNICODE : TCHAR* tstr = _T("char") ; TCHAR* tstr = _TEXT("char");
6. 输出
ANSI: printf("char"); Unicode: wprintf(L"char"); 通用: _tprintf(_T("char"));
7. 字符数和字节数
对于ANSI来说:字符数 = 字节数
对于Unicode来说:字符数 = 2 * 字节数
strlen, wcslen or _tcslen 返回的是字符数
sizeof( TCHAR ) 返回的是字节数
pBuffer = (TCHAR*) malloc (128 * sizeof(TCHAR) );