多字节字符集——每个字符的编码宽度不一,可为一个字节或多个字节。
(1)ASCII字符只占一个字节
(2)对于中文、日文等用两个字节
(3)一个字符串中,如何区分哪个是中文字符,那个是ASCII字符呢?
“Windows程序设计”16进制(10进制)的编码
W |
i |
n |
d |
o |
w |
s |
程 |
序 |
设 |
计 |
|
57 |
69 |
6E |
64 |
6F |
77 |
73 |
B3 CC |
D0 F2 |
C9 E8 |
BC C6 |
0 |
87 |
105 |
110 |
100 |
111 |
119 |
115 |
-77 -52 |
-48 -14 |
-55 -24 |
-68 -58 |
0 |
①说明:ASCII码为一个字节,中文为两个字节,均为负数
②优点:节约内存。
③缺点:每次查找,都需要从头到尾扫描,效率低。
char c[] ="Windows程序设计";
printf("%d\n",sizeof(c)); //输出16,数组总长度为16字节,含\0
printf("%d\n",strlen(c)); //输出15,字符的长度为15个字节,不含\0
宽字节字符集——每个字符的编码宽度都相等,均是两个字节
(1)ASCII字符的处理。扩充为两个字节,在原先的字节前补充一个字节0x00
(2)结束符为两个\0
(3)字符串的解释都是两个字符为单位进行的。所以查找效率快,但内存占用大。
“Windows程序设计”16进制的编码:
W |
i |
n |
d |
o |
w |
s |
程 |
序 |
设 |
计 |
|
0057 |
0069 |
006E |
0064 |
006F |
0077 |
0073 |
7A0B |
5E8F |
8BBE |
8BA1 |
0000 |
wchar_t c[] = L"Windows程序设计";
printf("%d\n",sizeof(c)); //输出24,数组总长度为16字节,含结束符
printf("%d\n",wcslen(c)); //输出11,字符的长度为11个,不含结束符
兼容两种的字符集——如何兼容呢?
#ifdef _UNICODE
#define _tcslen wcslen
#define TCHAR wchar_t
#define LPTSTR wchar_t*
#define _T(x) L##x
#else
#define _tcslen strlen
#define TCHAR char
#define LPTSTR char*
#define _T(x) x
#endif
【例】TCHAR c[] = _T("Windows程序设计");
//多字节字符集下
printf("%d\n",sizeof(c)); //16
printf("%d\n",_tcslen(c)); //15
//宽字符集下
printf("%d\n",sizeof(c)); //24
printf("%d\n",_tcslen(c)); //11
字符集的对比
ASCII |
Unicode |
通用版本 |
|
字符类型 |
char\CHAR |
wchar_t\WCHAR |
TCHAR |
函数两种版本 |
printf |
wprintf |
_tprintf |
【例】
#include <stdio.h>
#include <locale.h>
#include <tchar.h>
int main()
{
//ASCII字符集
//char c = 'A'; //char为一个字节
//char str[] = "中国"; //在未出现Unicode前的用法,在求字符串长度时会出问题。
//printf("%c\n", c);
//printf("%s\n", str);
//printf("长度:%d\n",strlen(str));//长度为4,对于ASCII来说,一个汉字为2个字节,被看成是两个字符了。
//Unicode字符集
//wchar_t c = L'中'; //Unicode,两个字节
//wchar_t str[] = L"中国"; //Unicode字符串的用法
//setlocale(LC_ALL,"chs");
//wprintf(L"%lc\n", c);//wprintf要求第1个参数为L型的,须加个大写的L
//wprintf(L"%ls\n",str);
//wprintf(L"%d\n",wcslen(str));//长度为2,Unicode字符。注意与上面ASCII字符集的比较
//通用的类型与函数
TCHAR str[] = _T("中国");
setlocale(LC_ALL,"chs");
_tprintf(_T("%s\n"),str);
_tprintf(_T("%d\n"),_tcslen(str));
return 0;
}
Windows中的字符串函数
通用版本 |
C语言中的ASCII版本 |
lstrlen |
strlen |
Lstrcpy |
strcpy |
Lstrcpyn |
strcpyn |
lstrcat |
strcat |
lstrcmp |
strcmp |
lstrcmpi |
strcmpi |
//ASCII码版
int WINAPI WinMain(HINSTANCEhInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
int a= 12;
char szBuffer[100];
sprintf_s(szBuffer,100,"Hello %d\n", a); //在内存中格式化字符串,标准c语言版本
MessageBoxA(NULL,szBuffer, "Hello ASCII", MB_OK | MB_ICONINFORMATION); //带A
return0;
}
//Unicode版
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
int a= 12;
wchar_tszBuffer[100]; //WCHAR
swprintf_s(szBuffer,100, L"Hello %d\n", a); //在内存中格式化字符串,标准c语言版
MessageBoxW(NULL,szBuffer, L"Hello Unicode", MB_OK | MB_ICONINFORMATION); //带W
return0;
}
//通用版本
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
int a= 12;
TCHARszBuffer[100]; //WCHAR
_stprintf_s(szBuffer,100,TEXT("Hello %d\n"), a); //在内存中格式化字符串,微软版本的在tchar.h中
MessageBox(NULL,szBuffer, TEXT("Hello TCHAR"), MB_OK | MB_ICONINFORMATION);
return0;
}