C++中宽字节的编码方式

C++中宽字节的编码方式

     C++中宽字节的编码方式

Unicode,UTF-8,UTF-16 完整的说明参见 Wiki。简单来说,Unicode 定义了所有可以用来表示字符的数值集合(称之为 Code Point),而UTF-8 和 UTF-16 等 UTF 标准定义了这些数值和字符的映射关系--Unicode的具体实现

        UTF-8 优势:UTF-8 没有字节序的概念(大小端问题),所以特别适合用于字符串的网络数据传输。UTF-8 劣势:本地字符串处理过程中,如果使用 UTF-8,对于英文字符的处理没有太大的问题,因为一个 char 变量表示一个英文字符。但是对于中文等远东字符集来说,就比较坑爹了。char str[]; str[0]并不能完整表示一个汉字。UTF-8 编码格式下,一个汉字需要至少3个char才能表示。这对于通过下标来操作字符串的操作来说是非常痛苦的一件事情。另外,一个汉字需要至少3个char来表示,也让汉字在网络传输占用太多流量。

        UTF-16优势:UTF-16 LE是 windows 上默认的 Unicode 编码方式,使用 wchar_t 表示。所有 wchar_t *类型的字符串(包括硬编码在.h/.cpp 里的字符串字面值),VC 都自动采用 UTF-16 的编码(字符串字面值,literal string,存在很多坑。特别是 char *类型的字面值,最终内存使用何种编码方式完全取决于当前文件的编码方式。也就是说当前文件如果是 GBK 编码的,那么文件里 char * str = "中午",str 指向的内存字符串二进制是 使用 GBK 编码的。如果文件编码是 UTF-8,那么内存是使用 UTF-8 编码。所以为什么一直要强调字符串应该放在资源文件里,而不是硬编码 在.h/.cpp 文件里!)。UTF-16 另一个优势就是常用字符都可以使用两个字节表示,也就是一个 wchar_t(Windows平台)。所以,在 Windows 平台上,特别适合使用 wchar_t 来作为字符串的存储基类型。一个 wchar_t 表示一个字符。操作使用非常方便。UTF-16劣势:没有统一的表示 UTF-16 编码的字符类型。C++98/03 里对 wchar_t 的定义是非常宽泛的。这导致在 Windows 平台上,wchar_t 是 2 字节 的;在 Unix-like 系统上是 4 字节的。代码移植上,可能会遇到挑战(我没移植过,所以不确定会有什么难度,以及难度有多大)。 即使最新的 C++11 里已经定义除了 char16_t 表示 UTF-16,MS 的 VS2013 还不支持 char16_t。所以目前使用 char16_t 还不具移植性。 据我了解,UTF-16 编码和 GBK 编码相比,还存在一个排序的劣势。也就是说,如果要按照汉语拼音的字母顺序对汉字进行排序,GBK 会得到 正确的结果,而 UTF-16 就不行。

 

Unicode 汉字编码表目前普遍采用的是 UCS-2,它用两个字节来编码一个字符, 比如汉字"经"的编码是 0x7ECF,UCS-2 用两个字节来编码字符,两个字节就是 16 位二进制, 2 的 16 次方等于 65536,所以 UCS-2 最多能编码 65536 个字符。编码从 0 到 127 的字符与 ASCII 编码的字符一样,比如字母 "a"的 Unicode 编码是 0x0061,十进制是 97,而"a"的 ASCII 编码是 0x61,十进制也是 97, 对于汉字的编码,事实上 Unicode 对汉字支持不怎么好,这也是没办法的, 简体和繁体总共有六七万个汉字,而 UCS-2 最多能表示 65536 个,才六万多个,所以 Unicode 只能排除一些几乎不用的汉字,好在常用的简体汉字也不过七千多个,为了能表示所有汉字,Unicode 也有 UCS-4 规范,就是用 4 个字节来编码字符,不过现在普遍采用的还是 UCS-2,只用 两个字节来编码。看一下 Unicode 对汉字的编码:

 -------------------------------------------------------------------

  U+   0   1  2   3  4   5   6  7   8   9   A  B  C  D  E  F 

4e00 一 丁 丂 七 丄 丅 丆 万 丈 三 上 下 丌 不 与 丏 

4e10 丐 丑 丒 专 且 丕 世 丗 丘 丙 业 丛 东 丝 丞 丟 

4e20 丠 両 丢 丣 两 严 並 丧 丨 丩 个 丫 丬 中 丮 丯 

4e30 丰 丱 串 丳 临 丵 丶 丷 丸 丹 为 主 丼 丽 举 丿 

4e40 乀 乁 乂 乃 乄 久 乆 乇 么 义 乊 之 乌 乍 乎 乏 

4e50 乐 乑 乒 乓 乔 乕 乖 乗 乘 乙 乚 乛 乜 九 乞 也 

4e60 习 乡 乢 乣 乤 乥 书 乧 乨 乩 乪 乫 乬 乭 乮 乯 

4e70 买 乱 乲 乳 乴 乵 乶 乷 乸 乹 乺 乻 乼 乽 乾 乿 

4e80 亀 亁 亂 亃 亄 亅 了 亇 予 争 亊 事 二 亍 于 亏 

4e90 亐 云 互 亓 五 井 亖 亗 亘 亙 亚 些 亜 亝 亞 亟 

4ea0 亠 亡 亢 亣 交 亥 亦 产 亨 亩 亪 享 京 亭 亮 亯 

4eb0 亰 亱 亲 亳 亴 亵 亶 亷 亸 亹 人 亻 亼 亽 亾 亿 

4ec0 什 仁 仂 仃 仄 仅 仆 仇 仈 仉 今 介 仌 仍 从 仏 

4ed0 仐 仑 仒 仓 仔 仕 他 仗 付 仙 仚 仛 仜 仝 仞 仟 

4ee0 仠 仡 仢 代 令 以 仦 仧 仨 仩 仪 仫 们 仭 仮 仯 

4ef0 仰 仱 仲 仳 仴 仵 件 价 仸 仹 仺 任 仼 份 仾 仿 

4f00 伀 企 伂 伃 伄 伅 伆 伇 伈 伉 伊 伋 伌 伍 伎 伏 

4f10 伐 休 伒 伓 伔 伕 伖 众 优 伙 会 伛 伜 伝 伞 伟 

4f20 传 伡 伢 伣 伤 伥 伦 伧 伨 伩 伪 伫 伬 伭 伮 伯

4f30 估 伱 伲 伳 伴 伵 伶 伷 伸 伹 伺 伻 似 伽 伾 伿 

4f40 佀 佁 佂 佃 佄 佅 但 佇 佈 佉 佊 佋 佌 位 低 住 

4f50 佐 佑 佒 体 佔 何 佖 佗 佘 余 佚 佛 作 佝 佞 佟 

4f60 你 佡 佢 

 

-------------------------------------------------------------------

UTF-16和UCS-2都是Unicode的编码方式。

 

Unicode使用一个确定的名字和一个叫做码位(code point)的整数来定义一个字符。例如©字符被命名为“copyright sign”并且有一个值为U+00A9(0xA9,十进制169)的码位。

Unicode的码空间从U+0000到U+10FFFF,共有1,112,064个码位(code point)可用来映射字符. Unicode的码空间可以划分为17个平面(plane),每个平面包含216(65,536)个码位。每个平面的码位可表示为从U+xx0000到U+xxFFFF, 其中xx表示十六进制值从0016 到1016,共计17个平面。

第一个Unicode平面(码位从U+0000至U+FFFF)包含了最常用的字符,该平面被称为基本多语言平面(Basic Multilingual Plane),缩写为BMP。其他平面称为辅助平面(Supplementary Planes)。

UCS-2 (2-byte Universal Character Set)是一种定长的编码方式,UCS-2仅仅简单的使用一个16位码元来表示码位,也就是说在0到0xFFFF的码位范围内,它和UTF-16基本一致。

UTF-16 (16-bit Unicode Transformation Format)是UCS-2的拓展,它可以表示BMP以为的字符。UTF-16使用一个或者两个16位的码元来表示码位,这样就可以对0到0x10FFFF的码位进行编码。

例如,在UCS-2和UTF-16中,BMP中的字符U+00A9 copyright sign(©)都被编码为0x00A9。

但是在BMP之外的字符,例如?,只能用UTF-16进行编码,使用两个16为码元来表示:0xD834 0xDF06。这被称作代理对,值得注意的是一个代理对仅仅表示一个字符,而不是两个。UCS-2并没有代理对的概念,所以会将0xD834 0xDF06解释为两个字符。

简单的说,UTF-16可看成是UCS-2的父集。在没有辅助平面字符(surrogate code points)前,UTF-16与UCS-2所指的是同一的意思。(严格的说这并不正确,因为在UTF-16中从U+D800到U+DFFF的码位不对应于任何字符,而在使用UCS-2的时代,U+D800到U+DFFF内的值被占用。)但当引入辅助平面字符后,就称为UTF-16了。

一般认为Windows下以16bit表示的Unicode并不是UTF-16,而是UCS-2。UCS-2是一种编码格式,同时也是指以一一对应关系的Unicode实现。在UCS-2中只能表示U+0000到U+FFFF的BMP(Basic Multilingual Plane ) Unicode编码范围,属于定长的Unicode实现,而UTF-16是变长的,类似于UTF-8的实现,但是由于其字节长度的增加,所以BMP部分也做到了一一对应,但是其通过两个双字节的组合可以做到表示全部Unicode,表示范围从U+0000 到 U+10FFFF。关于这一点,我在很多地方都看到混淆了,混的我自己都有点不太肯定自己的说法了,还好在《UTF-16/UCS-2》中还是区别开了,不然我不知道从哪里去寻找一个正确答案。(哪怕在IBM的相关网页上都将UCS-2作为UTF-16的别名列出)

 

《UTF-16/UCS-2》文中有以下内容:

UTF-16 is the native internal representation of text in the Microsoft Windows 2000/XP/2003/Vista/CEQualcomm BREW operating systems; theJava and .NET bytecode environments; Mac OS X's Cocoa and Core Foundation frameworks; and the Qt cross-platform graphical widget toolkit.[1][2][citation needed]

Symbian OS used in Nokia S60 handsets and Sony Ericsson UIQ handsets uses UCS-2.

The Joliet file system, used in CD-ROM media, encodes filenames using UCS-2BE (up to 64 Unicode characters per file).

Older Windows NT systems (prior to Windows 2000) only support UCS-2.[3]. In Windows XP, no code point above U+FFFF is included in any font delivered with Windows for European languages, possibly with Chinese Windows versions.[clarification needed

 

转自:http://blog.sina.com.cn/s/blog_7ade159d0102xbfc.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值