ASCII字符集、Unicode字符集下UTF-8 和UTF-16编码、GBK(GB2312)字符集

ASCII字符集、Unicode字符集下UTF-8 和UTF-16编码、GBK(GB2312)字符集https www cnblogs com Braveliu p 9460812 html 字符集

大家好,欢迎来到IT知识分享网。

什么是字符集

字符集是多个字符的集合,字符集种类较多,每个字符集包含的字符个数不同,常见字符集有:ASCII字符集、ISO 8859字符集、GB2312字符集、BIG5字符集、GB18030字符集、unicode字符集等.

什么是字符编码?

ASCII

ASCII码是西欧编码的方式,采取7位编码,所以是2^7=128,共可以表示128个字符,包括34个字符,(如换行LF,回车CR等),其余94位为英文字母和标点符号及运算符号等。

ASCII表

GB2312字符集

GB2312 是对 ASCII 的中文扩展。兼容ASCII。

GBK

GBK 兼容ASCLL 兼容 GB2312 是GB2312的扩展。  中文 占2字节
但是中国的汉字太多了,我们很快就就发现有许多人的人名没有办法在这里打出来,不得不继续把 GB2312 没有用到的码位找出来用上。后来还是不够用,于是干脆不再要求低字节一定是127号之后的内码,只要第一个字节是大于127就固定表示这是一个汉字的开始,不管后面跟的是不是扩展字符集里的内容。结果扩展之后的编码方案被称为 “GBK” 标准,GBK 包括了 GB2312 的所有内容,同时又增加了近20000个新的汉字(包括繁体字)和符号。

Unicode 是「字符集」

最初的unicode编码是固定长度的,16位,也就是两个字节代表一个字符,这样一共可以表示65536个字符。显然,这样要表示各种语言中所有的字符是远远不够的。Unicode4.0规范考虑到了这种情况,定义了一组附加字符编码,附加字符编码采用2个16位来表示,这样最多可以定义个附加字符,目前unicode4.0只定义了45960个附加字符。

Unicode长度为4字节。

Unicode为世界上所有字符都分配了一个唯一的数字编号,这个编号范围从 0x000000 到 0x10FFFF(十六进制),有110多万,每个字符都有一个唯一的Unicode编号,这个编号一般写成16进制。例如「知」的码位是 30693,记作 U+77E5(30693 的十六进制为 0x77E5)。

它是一种规定,Unicode本身只规定了每个字符的数字编号是多少,并没有规定这个编号如何存储。

Unicode编码体系下需要4个字节,其余3个字节为空。这就导致资源的浪费。

为了解决Unicode带来的资源浪费,采用变长的字节码(如UTF-8)或者定长的字节码表示,可以理解成 压缩Unicode。

ASCII字符集、Unicode字符集下UTF-8 和UTF-16编码、GBK(GB2312)字符集

 定长字符编码

UCS-2

 UCS-2(Universal Character Set coded in 2 octets),是用定长2个字节来表示字符(定长编码),其取值范围为 U+0000~U+FFFF。 
Unicode当前默认的版本是UCS-2,UCS-2 编码 与 Unicode码 完全一样,6w+的字符量已经足以用于全球的主要语言的大多数字符。
UCS-2的优点:
对于亚洲字符的存储空间需求比UTF-8少,因为每个字符都是2个字节。
处理字符的速度比UTF-8更快,因为是固定长度编码的。
对于windows和java的支持更好。




window和java则支持UCS-2。

ASCII字符集、Unicode字符集下UTF-8 和UTF-16编码、GBK(GB2312)字符集

UCS-4

即用四个字节表示代码点。它的范围为 U+00000000~U+7FFFFFFF,允许表示一百多万个字符。其中 U+00000000~U+0000FFFF和UCS-2是一样的。

可变长度字符编码

UTF-8

Unicode是一个字符集,而UTF-8是Unicode的其中一种,UTF-8以字节为单位对Unicode进行编码。UTF-8中英文字符占一个字节,汉字占三个字节

其中:  字符集:为每一个「字符」分配一个唯一的 ID(学名为码位 / 码点 / Code Point) 

编码规则:将「码位」转换为字节序列的规则(编码/解码 可以理解为 加密/解密 的过程)

 UTF-8 顾名思义,是一套以 8 位为一个编码单位的可变长编码。会将一个码位编码为 1 到 4 个字节这个变化是根据 Unicode 编号的大小有关,编号小的使用的字节就少,编号大的使用的字节就多。

UTF-8使用1~4字节为每个字符编码:

·一个US-ASCIl字符只需1字节编码(Unicode范围由U+0000~U+007F)。

·带有变音符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文等字母则需要2字节编码(Unicode范围由U+0080~U+07FF)。

·其他语言的字符(包括中日韩文字、东南亚文字、中东文字等)包含了大部分常用字,使用3字节编码。

·其他极少使用的语言字符使用4字节编码

UTF-8是这样做的:

1. 单字节的字符,字节的第一位设为0,对于英语文本,UTF-8码只占用一个字节,和ASCII码完全相同;

2. n个字节的字符(n>1),第一个字节的前n位设为1,第n+1位设为0,后面字节的前两位都设为10,这n个字节的其余空位填充该字符unicode码,高位用0补足。

Unicode符号范围 | UTF-8编码方式 (十六进制) | (二进制) ----------------------+--------------------------------------------- 0000 0000-0000 007F | 0xxxxxxx 0000 0080-0000 07FF | 110xxxxx 10xxxxxx 0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx 0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

因此:是任何字符对应的数字保存时所占的空间是可变的,使用一至四个字节为每个字符编码,其中大部分汉字采用三个字节编码,少量不常用汉字采用四个字节编码.而UTF-8由于里面有额外的标志信息,所有一个字节只能表示2的7次方128个字符,两个字节只能表示2的11次方2048个字符,而三个字节能表示2的16次方,65536个字符。

优点:兼容了 ASCII 码,节约空间,且没有字节顺序的问题。

Unix平台中普遍支持UTF-8字符集。

UTF-16

UTF-16:使用二或四个字节为每个字符编码,其中大部分汉字采用两个字节编码,少量不常用汉字采用四个字节编码。是任何字符对应的数字都用两个字节来保存,但如果都是英文字母(一个字节能表示一个字符)这样做有点浪费。由于UTF-16不需要用其它字符来做标志,所以两字节也就是2的16次能表示65536个字符。

缺点:仍不兼容 ASCII 码(一个英文字母要用2个字节来表示),仍有大小端格式问题。

常见的场景

1.Qt Creator使用的是utf-8来读取文本文件.

qt MSVC编码是windows本地的字符集如GB2312

相当于编译保存是GB2312,运行解码是utf-8.不匹配,导致乱码。

解决办法:qt 使用msvc编译器出现中文乱码的问题_小飞侠hello的博客-CSDN博客_qt msvc编译器中文字符串编译报错及乱码问题

Qt 自带的mingw 一般不会出现乱码问题.

2. vs里面的unicode字符集就是采用的utf-16(用二个字节存储一个字符)或者说是usc-2.

3.QString 内部是以 16 位的 QChar 来存储(Unicode 的一种,但不是 utf-8,即utf-16)

互换函数

具体见:

#define CP_ACP                    0           // default to ANSI code page

#define CP_UTF8                   65001       // UTF-8 translation

string 转 wstring 或者说 char * 转 wchar*

这就是为了防止string类型的乱码,需要把string 转换成wstring.

在MFC中,Cstring str = wstring wstr.c_str();

//#define CP_ACP 0 // default to ANSI code page wstring stringTowstring(string str, size_t m_encode = CP_ACP) { const char* cchar =str.c_str(); wchar_t *m_wchar; int len = MultiByteToWideChar(m_encode, 0, cchar, strlen(cchar), NULL, 0); m_wchar = new wchar_t[len + 1]; MultiByteToWideChar(m_encode, 0, cchar, strlen(cchar), m_wchar, len); m_wchar[len] = '\0'; wstring strtemp = m_wchar; delete m_wchar; return strtemp; } int main() { string staa("你好,hello"); //在vs中,straa[0] 不能显示出“你”,需要转换成wstring wstring wstr = stringTowstring(staa); }

wstring 转 string 或者说 wchar * 转 char*

string wstringTostring(wstring wstr, size_t m_encode = CP_ACP) { const wchar_t* wchar = wstr.c_str(); char * m_char; int len = WideCharToMultiByte(m_encode, 0, wchar, wcslen(wchar), NULL, 0, NULL, NULL); m_char = new char[len + 1]; WideCharToMultiByte(m_encode, 0, wchar, wcslen(wchar), m_char, len, NULL, NULL); m_char[len] = '\0'; string str = m_char; delete m_char; return str; }

UTF8 转换成GBK2312

char* CWininetHttp::UtfToGbk(const char* utf8) {     int len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);     wchar_t* wstr = new wchar_t[len + 1];     memset(wstr, 0, len + 1);     MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, len);     len = WideCharToMultiByte(CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL);     char* str = new char[len + 1];     memset(str, 0, len + 1);     WideCharToMultiByte(CP_ACP, 0, wstr, -1, str, len, NULL, NULL);     if (wstr) delete[] wstr;     return str; } string staa("你好,hello"); cout << staa[0] << endl; wstring wstr = stringTowstring(staa); string strd = wstringTostring(wstr);

  gb2312转换成utf8

    string gb2312_to_utf8(const char* gb2312)     {         int len = MultiByteToWideChar(CP_ACP, 0, gb2312, -1, NULL, 0);         wchar_t* wstr = new wchar_t[len + 1];         memset(wstr, 0, len + 1);         MultiByteToWideChar(CP_ACP, 0, gb2312, -1, wstr, len);         len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);         char* str = new char[len + 1];         memset(str, 0, len + 1);         WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);         string strTemp = str;         if (wstr)             delete[] wstr;         if (str)             delete[] str;           return strTemp; }

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/118545.html

(0)
上一篇 2025-11-12 13:20
下一篇 2025-11-12 13:33

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信