多字节字符集

来源:互联网 发布:电钢琴 耳机 知乎 编辑:程序博客网 时间:2024/05/21 10:16

文章转摘自互联网。

常用的代码页由CP_ACP和CP_UTF8两个。

使用CP_ACP代码页就实现了ANSI与Unicode之间的转换。

使用CP_UTF8代码页就实现了UTF-8与Unicode之间的转换。

其实好记点 MultiByte=CodePage

WideCharToMultiByte   :unicode到代码页

MultiByteToWideChar   :代码页到Unicode

C 语言原本是在英文环境中设计的,主要的字符集是7 位的ASCII 码。从此开始,8 位的byte(字节)变成最常见的字符编码单位,但是国际化软件必须能够表示不同的字符,而这些字符数量庞大,无法使用一个字节编码,于是世界上使用各式各样多字节的字符编码集合已经有数十年了,比如用来表示“非拉丁字母”以及“非字母”的中、日、韩文字系统。在1994 年,“Normative Addendum 1”(基准增补一)的采用,让ISO C 可以标准化两种表示大型字符集的方法:宽字符(wide character,该字符集内每个字符使用相同的位长)以及多字节字符(multibyte character,每个字符可以是一到多个字节不等,而某个字节序列的字符值由字符串或流(stream)所在的环境背景决定)。
注意: 虽然C现在提供抽象机制,可以处理和转换不同种类的编码集合,但语言本身并没有定义或指定任何编码集合,或任何字符集(除前一节提到的基本源代码字符集和基本运行字符集外)。换句话说,这部分是由个别的实现版本指定如何编码宽字符,以及要支持什么类型的多字节字符编码机制。
自从1994 年的增补之后,C 不只提供char类型,还提供wchar_t类型(宽字符),此类型定义在stddef.h 头文件中。wchar_t 类型足以表示某个实现版本扩展字符集的任何元素。
虽然C 标准没有支持Unicode 字符集,许多实现版本使用Unicode 转换格式UTF-16 和UTF-32(参考http://www.unicode.org)来处理宽字符。Unicode 标准和ISO/IEC 10646标准相当接近,而且是许多既有字符集(包括7 位的ASCII)的超集。如果遵循Unicode标准,wchar_t类型至少是16或32位长,而wchar_t类型的一个值就代表一个Unicode字符。比方说,下列的定义将变量wc 初始化为希腊字母α。

wchar_t wc = '\x3b1';此转义符以“\x”起头,后面接着十六进制的数字,会将这个数字所代表的字符赋值到变量中。在这个例子中,此字符是小写的alpha。在多字节字符集中,每个字符的编码宽度都不等,可以是一个字节,也可以是多个字节。源代码字符集和运行字符集都可能包含多字节字符,如果真的包含多字节字符的话,那么基本字符集中的每个字符都只会占用一个字节(完全没有多字节的字符),空字符是唯一的例外,空字符可能会占用任意个数的字节(但这些字节内全部的位都必须为0)。多字节字符可以被用于字符的常量、字符串字面值(string literal)、标识符(identifier)、注释(comment),以及头文件。许多的多字节字符集被设计来支持特定国家的语言,例如JIS 字符集(日本业界标准,Japanese Industrial Standard)。多字节UTF-8 字符集是由Unicode Consortium(万国码联盟)定义的,可以表示Unicode 字符集的所有字符。
UTF-8 字符所使用的空间大小从一个字节到四个字节都有可能。多字节字符和宽字符(也就是wchar_t)的主要差异在于宽字符占用的字节数目都一样,而多字节字符的字节数目不等,这样的表示方式使得多字节字符串比宽字符串更难处理。
比方说,即使字符'A'可以用一个字节来表示,但是要在多字节的字符串中找到此字符,就不能使用简单的字节比对,因为即使在某个位置找到相符合的字节,此字节也不见得是一个字符,它可能是另一个不同字符的一部分。然而,多字节字符相当适合用来将文字存储成文件(参见第13 章)。
C 提供了一些标准函数,可以将多字节字符转换为wchar_t,或将宽字符转换为多字节字符。比方说,如果C 编译器使用Unicode 标准的UTF-16 和UTF-8,那么下面调用wctomb()函数就可以获得字符α 的多字节表示方式(注:wctomb = wide character to multibyte)。

wchar_t wc = L'\x3B1'; // 小写的希腊字母alpha,α
char mbStr[10] = "";
int nBytes = 0;
nBytes = wctomb( mbStr, wc );

在调用此函数之后,mbStr数组会得到多字节的字符,在这个例子中,也就是"\xCE\xB1"符号。此wctomb()函数的返回值是“所需要的字节个数”,在这个例子中,被赋值到变量nBytes 的值是2,意思是:希腊小写字母alpha 在多字节字符中需要占用两个字节。

什么是UTF-8?它与UNICODE是一回事吗? 
Unicode的最初目标,是用1个16位的编码来为超过65000字符提供映射。但这还不够,它不能覆盖全部历史上的文字,也不能解决传输的问题(implantation head-ache's),尤其在那些基于网络的应用中。已有的软件必须做大量的工作来程序16位的数据。 
因此,Unicode用一些基本的保留字符制定了三套编码方式。它们分别是UTF-8,UTF-16和UTF-32。正如名字所示,在UTF-8中,字符是以8位序列来编码的,用一个或几个字节来表示一个字符。这种方式的最大好处,是UTF-8保留了ASCII字符的编码做为它的一部分,例如,在UTF-8和ASCII中,“A”的编码都是0x41. 
UTF-16和UTF-32分别是Unicode的16位和32位编码方式。考虑到最初的目的,通常说的Unicode就是指UTF-16。在讨论Unicode时,搞清楚哪种编码方式非常重要。Unicdoe相关的技术介绍参见http://www.unicode.org/unicode/standard/principles.html.