本例介绍了微软C语言使用的两种字符集, ASCII(ISO-8859-1)和UNICODE(UTF-16)字符集以及它们的区别。
注意,对字符集缺乏概念的同学, 请仔细阅读本例, 字符集是整个Win32编程基础的重中之重。
从程序中我们可以学习到, 除过早期C语言支持的ASCII编码外, 新的C语言还支持UNICODE编码, 这是一种可以包含国际化文字的编码格式, 是Windows2000之后版本Windows平台统一采用的文字编码格式。
C语言同时支持ASCII编码和UNICODE编码, 所以对应的数据类型也就提供了两个, char类型和wchar_t类型。对应的字符、字符串操作函数也同时提供了两套, 普通的C标准字符串函数库和以w开头的UNICODE版本扩展函数库(注意, 原有以str开头的字符串函数, 其UNICODE版本是以wcs开头的)
| 1 | #include <stdio.h> |
| 2 | #include <stdlib.h> |
| 3 | #include <string.h> |
| 4 | #include <locale.h> |
| 5 | |
| 6 | // 定义缓冲区长度为256个字符 |
| 7 | // (注意,这里为什么用"字符"而不是"字节") |
| 8 | #define BUFFER_LEN256 |
| 9 | |
| 10 | intmain(intargc,char*argv[]) |
| 11 | { |
| 12 | //定义一个ASCII字符变量 |
| 13 | charce='A'; |
| 14 | //定义一个UNICODE字符变量 |
| 15 | wchar_twce='A'; |
| 16 | |
| 17 | // 定义一个ASCII字符串变量,包含一个汉字 |
| 18 | //(由于一个汉字占用2字节(GB10080编码)), |
| 19 | // 所以一个char类型变量无法存储,需要一个字符串来存储, |
| 20 | //所以实际上这个“大”字占据了3个字节,两个字节存放字符 |
| 21 | //本身编码,还有一个/0结束符 |
| 22 | charszC[]="大"; |
| 23 | |
| 24 | // 定义一个UNICODE字符变量,wchar_t变量可以存放一个汉 |
| 25 | //字,注意字符前的大写L,这个符号表示该字符为UNICODE字 |
| 26 | //符集字符 |
| 27 | wchar_twcC=L'大'; |
| 28 | |
| 29 | //定义ASCII字符集字符串变量 |
| 30 | constcharcszHello[]="Hello"; |
| 31 | |
| 32 | // 定义UNICODE字符集字符串变量,注意字符串前的大写L, |
| 33 | //这个符号表示该字符串为UNICODE字符集字符串 |
| 34 | constwchar_tcwszHello[]=L"Hello"; |
| 35 | |
| 36 | /********************************************************* |
| 37 | * 学习字符集,一开始要搞清楚不同字符集占据的空间大小。 |
| 38 | * ASCII字符集每个字符占据1字节,使用char表示 |
| 39 | * UNICODE字符集每个字符占据2字节,使用wchar_t(部分 |
| 40 | *版本C语言使用unsignedshort)表示 |
| 41 | *********************************************************/ |
| 42 | |
| 43 | // 定义ASCII字符集字符串指针 |
| 44 | //(思考一下,pcszHello和cszHello这两个变量定义的区别在 |
| 45 | //哪里,它们各自代表了什么?) |
| 46 | constchar*pcszHello="大家好"; |
| 47 | |
| 48 | //定义UNICODE字符集字符串指针 |
| 49 | constwchar_t*pcwszHello=L"大家好"; |
| 50 | |
| 51 | // 定义BUFFER_LEN长度存放字节的缓冲区 |
| 52 | //(定义的同时初始化缓冲区是一个好习惯) |
| 53 | charszBuffer[BUFFER_LEN]=""; |
| 54 | |
| 55 | //定义BUFFER_LEN长度存放UNICODE字符的缓冲区 |
| 56 | wchar_twszBuffer[BUFFER_LEN]; |
| 57 | |
| 58 | //使用memset函数可以初始化任何数组,包括字符串数组 |
| 59 | memset(wszBuffer,0,sizeof(wszBuffer)); |
| 60 | |
| 61 | // 在最新的C语言标准中,所有UNICODE字符在显示前需要 |
| 62 | //设置其国家代码(或称为地域信息),这里设置为中国 |
| 63 | // LC_ALL表示设置所有相关项目为中国,包括文字、时间和 |
| 64 | //货币 |
| 65 | _wsetlocale(LC_ALL,L"zhi"); |
| 66 | |
| 67 | //输出ASCII英文字符 |
| 68 | printf("sizeof%cis%d,codeis:%u",ce,sizeof(ce),(int)ce); |
| 69 | |
| 70 | //输出UNICODE英文字符 |
| 71 | wprintf(L"/nsizeof%cis%d,codeis:%u",wce,sizeof(wce),(int)wce); |
| 72 | |
| 73 | /********************************************************* |
| 74 | * 通过上述代码可以发现,对于英文字符,ASCII编码和 |
| 75 | *UNICODE编码的内码相同,但占用空间不同 |
| 76 | *********************************************************/ |
| 77 | |
| 78 | //输出ASCII中文字符(实际是一个字符串) |
| 79 | printf("/nsizeof%sis%d,codeis:%u",szC,sizeof(szC),(int)*(unsignedshort*)szC); |
| 80 | |
| 81 | //输出UNICODE中文字符 |
| 82 | wprintf(L"/nsizeof%cis%d,codeis:%u",wcC,sizeof(wcC),(int)wcC); |
| 83 | |
| 84 | /********************************************************* |
| 85 | * 通过上述代码可以发现,GB10080编码和UNICODE编码在 |
| 86 | *编码“大”字时,编码值是不同的,但都占据2字节空间 |
| 87 | *********************************************************/ |
| 88 | |
| 89 | //使用printf函数输出ASCII字符集字符串并输出其占据空间的字节数 |
| 90 | printf("/nsizeof%sis%d",cszHello,sizeof(cszHello)); |
| 91 | |
| 92 | //使用wprintf函数输出UNICODE字符集字符串并输出其占据空间的字节数 |
| 93 | wprintf(L"/nsizeof%sis%d",cwszHello,sizeof(cwszHello)); |
| 94 | |
| 95 | /********************************************************* |
| 96 | *通过上述的练习可以发现: |
| 97 | * ASCII字符集字符串长度和其占用空间的字节数一致 |
| 98 | *(包括结束符/0,占据1byte) |
| 99 | * UNICODE字符集字符串长度是其占用空间字节数的2倍 |
| 100 | *(包括结束符/0,占据2byte),这一点和wchar_t类型为2字 |
| 101 | *节一致 |
| 102 | *********************************************************/ |
| 103 | |
| 104 | //使用strlen函数测量ASCII字符串长度 |
| 105 | printf("/nlengthof%sis%d",pcszHello,strlen(pcszHello)); |
| 106 | |
| 107 | //使用wcslen函数测量UNICODE字符串长度 |
| 108 | wprintf(L"/nlengthof%sis%d",pcwszHello,wcslen(pcwszHello)); |
| 109 | |
| 110 | //使用strcpy_s函数复制ASCII字符串(后缀为_s的函数是原函数的"安全版本", |
| 111 | //改进了可能出现缓冲区溢出问题的漏洞) |
| 112 | strcpy_s(szBuffer,BUFFER_LEN,cszHello); |
| 113 | |
| 114 | //使用strcat_s函数连接ASCII字符串 |
| 115 | strcat_s(szBuffer,BUFFER_LEN,pcszHello); |
| 116 | printf("/nlengthof%sis%d",szBuffer,strlen(szBuffer)); |
| 117 | |
| 118 | //使用wcscpy_s函数复制UNICODE字符串 |
| 119 | wcscpy_s(wszBuffer,BUFFER_LEN,cwszHello); |
| 120 | |
| 121 | //使用wcscat_s函数连接UNICODE字符串 |
| 122 | wcscat_s(wszBuffer,BUFFER_LEN,pcwszHello); |
| 123 | wprintf(L"/nlengthof%sis%d",wszBuffer,wcslen(wszBuffer)); |
| 124 | |
| 125 | wprintf(L"/n"); |
| 126 | system("pause"); |
| 127 | return0; |
| 128 |
} 现在的程序开发中,往往兼顾ANSI和Unicode,在C++中char是支持ANSI的字符串类型,wchar_t是支持Unicode的字符类型。将字节串转换成字符串的函数有mbstowcs(), MultiByteToWideChar(),将字符串装换成字节串的函数有wcstombs(), WideCharToMultiByte()。其中MultiByteToWideChar() 和 WideCharToMultiByte() 是 Windows API 函数, 而wcstombs()和mbstowcs()则是定义在C的函数库<stdlib.h>中。下边是一个使用ANSI字符串和UNICODE字符串的例子。 测量字符串长度的strlen函数的宽字元版是wcslen(wide-character string length:宽字串长度),并且在STRING.H(其中也说明了strlen)和WCHAR.H中均有说明。strlen函式说明如下: Unicode编码也存在许多的问题,那就是每个字符串都将占两倍的存储空间,而且函数执行的时候函数库要比常规的函数库要大.所以一般在开发中,出两个版本,一个是处理ASCII字符串,一个是处理Unicode的字符串.最好的解决办法是维护既能按ASCII编译又能按Unicode编译的单一原始码档案。
|
本文详细介绍了C语言中ASCII和UNICODE字符集的区别及其在编程中的应用。通过具体实例展示了不同字符集下字符和字符串的定义、存储及操作。
3792

被折叠的 条评论
为什么被折叠?



