logo资料库

utf-8/utf-16转换代码完整版.pdf

第1页 / 共5页
第2页 / 共5页
第3页 / 共5页
第4页 / 共5页
第5页 / 共5页
资料共5页,全文预览结束
详解字符编码  有问题欢迎发 Email: qiuduming@163com 最近需要对 Linux 与 Windows 平台下的字符传输出现乱码,对字符编码作了深究。参考 了网上的 UTF‐8/UTF‐16 转换的资料,只有 0x10000 以下的 Unicode 编码进行了转换;对其代 码进行了修改和补充,可以实现所有的 UTF‐8/UTF‐16 的转换,分享给大家。(看代码前提是 需了解 Unicode 的编码知识)。  介绍:  一、Ascii 编码(摘自维基百科)  ASCII(美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用 于显示现代英语,而其扩展版本 EASCII 则可以部分支持其他西欧语言,并等同于 国际标准 ISO/IEC 646。由于万维网使得 ASCII 广为通用,直到 2007 年 12 月,逐 渐被 Unicode 取代[2]。 ASCII 第一次以规范标准的型态发表是在 1967 年,最后一次更新则是在 1986 年, 至今为止共定义了 128 个字符;其中 33 个字符无法显示(一些终端提供了扩展, 使得这些字符可显示为诸如笑脸、扑克牌花式等 8-bit 符号),且这 33 个字符多 数都已是陈废的控制字符。控制字符的用途主要是用来操控已经处理过的文字。在 33 个字符之外的是 95 个可显示的字符,包含用键盘敲下空白键所产生的空白字符 也算 1 个可显示字符(显示为空白)。   二、ANSI 与 GBK 编码(摘自百度百科)  ANSI(American National Standards Institute),中文:美国国家标准学 会。 为使计算机支持更多语言,通常使用 0x80~0xFF 范围的多个字节来表示 1 个 字符。比如:汉字 '中' 在简体中文 Windows 操作系统中,使用 [0xD6,0xD0] 这 两个字节存储。对于 ANSI 编码而言,0x00~0x7F 之间的字符,依旧是 1 个字节代 表 1 个字符。这一点是 ANSI 编码与 UTF-16 编码之间最大也最明显的区别。比如“A 君是第 131 号”,在 ANSI 编码中,占用 12 个字节,而在 UTF-16 编码中,占用 16 个字节。因为 A 和 1、3、1 这 4 个字符,在 ANSI 编码中只各占 1 个字节,而在 UTF-16 编码中,是需要各占 2 个字节的。 不同的国家和地区制定了不同的标准,由此产生了 GB2312、GBK、Big5、 Shift_JIS 等各自的编码标准。这些使用 1 至 4 个字节来代表一个字符的各种汉 字延伸编码方式,称为 ANSI 编码。在简体中文 Windows 操作系统中,ANSI 编码 代表 GBK 编码;在日文 Windows 操作系统中,ANSI 编码代表 Shift_JIS 编码。 不 同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字, 存储在同一段 ANSI 编码的文本中。 当然对于 ANSI 编码而言,0x00~0x7F 之间的 字符,依旧是 1 个字节代表 1 个字符。这一点是 ASNI 编码与 Unicode 编码之间最 大也最明显的区别。
三、Unicode 编码(摘自维基百科)  Unicode(中文:万国码、国际码、统一码、单一码)是计算机科学领域里的 一项业界标准。它对世界上大部分的文字系统进行了整理、编码,使得电脑可以用 更为简单的方式来呈现和处理文字。  目前 Unicode 编码的范围是 0x0——0x10FFFF。Unicode 流行的编码方式有的 UCS‐2、UCS4 和 UTF‐8、UTF‐16、UTF‐32。  注:至于 UTF‐8、UTF‐16、UTF‐32 的编码方式,大家可以在维基百科上搜索,上面有详细的 介绍。  UTF‐8 和 UTF‐16 的转换代码:      #include   #include   #include   using namespace std;    typedef unsigned short utf16;  typedef unsigned char utf8;  void UTF8toUTF16(utf8* p8begin ,utf8* p8end,utf16* p16begin ,utf16* p16end)  {    utf8 * p8start = p8begin;    utf16* p16start = p16begin;    while (p8start<=p8end&&p16start<=p16end)    {                                                                            if (*p8start>=0&&*p8start<=0x7f)  {            }  else if (*p8start>=0xc0&&*p8start<=0xdf)  {                *p16start |= (*p8start++&0x1f)<<6;  //*p16start |= (*p8start++&0x3f);  *p16start |= (*p8start&0x3f);  if (p8start
p8start++;  if (p8start>4;  else if (*p8start>=0xe0&&*p8start<=0xef)  {                }  else if (*p8start>=0xf0&&*p8start<=0xf7&&p16start+1<=p16end)  {                *p16start |= (*p8start++&0x0f)<<12;      *p16start |= (*p8start++&0x3f)<<6;          //*p16start |= (*p8start++&0x3f);                          *p16start |= (*p8start&0x3f);                                                                                                            }    //*p16start = 0;  }      void UTF16toUTF8(utf16* p16begin ,utf16* p16end ,utf8* p8begin ,utf8* p8end)  {    utf8* p8start = p8begin;    utf16* p16start = p16begin;    while (p16start<=p16end&&p8start<=p8end)  p8start++;  if (p8start
break;  }  *p8start++ =(*p16start>>6)|0xc0;  //*p8start++ = ((*p16start)&0x3f)|0x80;  *p8start = ((*p16start)&0x3f)|0x80;  if (p8start0x7f&&*p16start<=0x7ff&&p8start+1<=p8end)  {                  {                                                                                else if(((0x7ff<*p16start&&*p16start<0xd800)|| \            (0xdfff<*p16start&&*p16start<0xffff))&&p8start+2<=p8end)                                                                    p8start+3<=p8end&&p16start+1<=p16end)                                      *p16start = (*p16start&0x3ff);  *p8start++ = (*p16start>>8)|0xf0;  *p8start++ = ((*p16start&0xff)>>2)|0x80;  *p8start = ((*p16start++&0x3)<<4)|0x80;  *p16start = (*p16start&0x3ff);  *p8start++ |= (*p16start>>6);  //*p8start++ = (*p16start&0x3f)|0x80;  *p8start = (*p16start&0x3f)|0x80;  *p8start++=(*p16start>>12)|0xe0;  *p8start++=((*p16start>>6)&0x3f)|0x80;  //*p8start++=(*p16start&0x3f)|0x80;  *p8start=(*p16start&0x3f)|0x80;  if (p8start
        p8start++;  if (p8start
分享到:
收藏