Windows程序员必须知道的字符编码和字符集

  1.  字符编码 (Character encoding)

在存储和传递文本过程中,为了使得所有电脑都能够正确的识别出文本内容,需要有一个统一的规则。

   2. 字符集 (Character Set) )

一般情况,一种编码方式对应一种字符集。如 ASCII,对应 ASCII 字符集。GBK 编码方式对应 GBK 字符集。但是也有一种编码方式,多种字符集的,Unicode 字符集有多种编码方式,如 utf-8,utf-16 等。

   3.  ASCII

ASCII(American Standard Code for Information Interchange,美国信息交换标准代码):使用 7 个 Bit 表示,共 128 个字符,刚好占用了一个字节中的后 7 位,共包括33 个控制字符和 95 个可显示字符。
.   4.  ANSI
ANSI (一种字符编码,此处不是表示美国国家标准学会的意思):ANSI 是为了让计算机支持更多的语言,而在 ASCII 的基础上的一种扩展字符编码。在不同语言操作上,ANSI 都表示当前计算机默认的编码方式。如在简体 Windows 操作下,ANSI 编码代表 GBK 编码;在繁体中文操作下,ANSI 编码代表 Big5 编码;在日文 Windows 操作系统中,ANSI 编码代表 Shift_JIS 编码;在英文操作系统下,ANSI 就是 ASCII 编码。
.   5.  MBCS
MBCS(Multi-Byte Character Set),早在 1980 年,中国就提出了使用 GB2312 编码方式来描述汉字。后来其他东亚国家也利用这种方式扩展 ASCII 编码字符集。台湾地区 5 大
企业推出的繁体 Big5 码,香港新加坡等后来也利用。日本韩国也相应推出了自己的编码方式。其实在这里,BIG5 既是编码方式,也是字符集。
  6.  GB2312(Guo Biao  2312) )
用双字节表示汉字,但是为了完全兼容 ASCII。汉字区“高字节”范围为 0xB0-0xF7,汉字区“低字节”范围 0xA1-0xFE,占用的码位 72*94=6768 个。
.   7.  GBK(Guo Biao Kuozhan)
后来发现 GB2312 的字符依然不够用,尤其是像“镕”(朱镕基)字打不出来。然后决定汉字区的低字节完全不兼容 ASCII,只要当前字符属于汉字码,那么其后的字符也属于汉字码。这样在兼容 GB2312 的基础上,再添加了近两万字和字符(兼容繁体、日本汉字、韩国汉字等)。GBK 同样也是一种编码方式和字符集两种意义合于一体。
.   8.  GB18030
有两版 GB18030-2000 和 GB18030-2005,是 GBK 的扩展版,并且完全兼容 GBK。GB18030和 utf-8 类似,是动态的,既有单字节字体,也有双字节字节(BGK),也有三字节,四字节字符。Windows 默认支持的是 GBK,若要支持 GB18030,需要下载安装单独的支持包。
.  9.  Big5 5
1984 年台湾五家公司联合创立,称大五码,英文 Big5。Big5 也是双字节编码方式,收录了一万多字符,但是没有包含中文简体。Big5 目前也被香港、新家坡等地区国家使用。Big5 保存的文本,在简体操作系统下显示乱码,但是有些编辑器会自动识别,然后将其按 GBK 繁体字显示,即可正常显示。如 Notepad++即有此功能。
  10.  全角
GBK 用两个字节重新表示了一遍在 ASCII 中出现的字符,这些字符被叫全角字符。
  11.  半角
出现在 ASCII 中的字符,被称作半角字符。
  12. e Unicode  字符集
Unicode 字符集是 1990 年提出的,能够表示全世界所有国家的所有字符。但是支持Unicode 字符集的编码方式都有多种,如 UTF-8,UTF-16 等。编码方式虽然不同,但是
都是可以完整表示所有 Unicode 字符的。VS 里默认的 Unicode 字符集是指 utf-16 编码的,即固定双字节为一个字符。
  13.  UTF- -8 8
因为 Unicode 能够包含全球所有的字符,而 utf-8 又是其中比较节省字符存储的一种实现方式。所以现在的网站,基本都是以 utf-8 编码方式来存储、传输和显示了。UTF-8
是变字节长度的,用 1-6 个字节表示字符。用一个字符表示常见字符,用二个字节表示拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚等,用三字
符表示常见汉字等,四个字节的字符比较少见。UTF-8 既能很方便存储英文,又能兼容全世界的字符,所以非常流行。
  14.  UTF- -8 8  解析算法
如果字节的第一位为 0,则 B 为 ASCII 码,并且 Byte 独立的表示一个字符;
如果字节的第一位为 1,第二位为 0,则 Byte 为一个非 ASCII 字符(该字符由多个字节表示)中的一个字节,并且不为字符的第一个字节编码;
如果字节的前两位为 1,第三位为 0,则 Byte 为一个非 ASCII 字符(该字符由多个字节
表示)中的第一个字节,并且该字符由两个字节表示;
如果字节的前三位为 1,第四位为 0,则 Byte 为一个非 ASCII 字符(该字符由多个字节表示)中的第一个字节,并且该字符由三个字节表示;
如果字节的前四位为 1,第五位为 0,则 Byte 为一个非 ASCII 字符(该字符由多个字节
表示)中的第一个字节,并且该字符由四个字节表示代码页(CodePag):代码页是字符集的数字值,不同的语言使用不同的代码页。例 如,ANSI
代码页为 1252,日文代码页为 932,简体中文(GBK)代码页为 936,繁体中文(Big5)代码页为 950。
  15.  语言包
系统默认的是 ANSI,但是同时也兼容 Unicode,这也是 Windows 的 API 有两套。当系统识别到当前字符是 Unicode 时,会以对应的 Unicode 编码方式去解码,Windows 支持的是 utf-8。解码之后,需要正确地显示出相应的字形,这个时候就需要语言包。如果没有语言包,会出现乱码。英文操作下,东亚语言归为一类,需要单独安装,安装时提示230MB。因为语言包比较大,所以在英文操作系统下,默认没有安装东亚语言包的,即不能正确显示 Unicode 下的东亚文字。至于语言包为什么这么大,猜测语言包必须得描述这个字体是如何点钩撇捺的等等。Windows 可以在控制面板中设置非 Unicode 程序显示语言。
  16.  大小端模式
由于 CPU 的缘故,存取数据分大端模式和小端模式,然后一些操作系统了软件也会有这样的区分。大端模式(Big-endian),是指数据的高字节,保存在内存的低地址中,而
数据的低字节,保存在内存的高地址中,这样的存储模式有点儿类似于把数据当作字符串顺序处理:地址由小向大增加,而数据从高位往低位放。小端模式(Little-endian),
是指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中,这种存储模式将地址的高低和数据位权有效地结合起来,高地址部分权值高,低地址部分
权值低,和我们的逻辑方法一致。
  17.  BOM(Byte Order Mark, 字节顺序标记) )
有一些文本编辑工具支持 UTF-8(BOM),字符 U+FEFF 如果出现在字节流的开头,则用来标识该字节流的字节序,是高位在前还是低位在前。接收者收到 FEFF,就表明这个字节
流是 Big-Endian 的;如果收到 FFFE,就表明这个字节流是 Little- Endian 的。Windows 文本默认的 Unicode 为大端 utf-16 存储,即以 FFFE 开头。BOM 主要应用Windows 下,而在某些系统下可能会出错,如 PHP 中容易读错。

编码  以此标记 (十六进制)  以此标记 (十进制)
UTF-8 EF BB BF 239 187 191
UTF-16(大端序) FE FF 254 255
UTF-16(小端序) FF FE 255 254
UTF-32(大端序) 00 00 FE FF 0 0 254 255
UTF-32(小端序) FF FE 00 00  255 254 0 0 

  18.  GBK 、e Unicode 他 他  UTF- -8 8  转换
UTF-8 和 GBK 同属于多字节 MultiByte,Unicode 默认是 UTF-16,即宽字符,两个字节。

GBK(ANSI)->Unicode->UTF-8,反向即 UTF-8->Unicode->GBK(ANSI)。

  1. [cpp] view plain copy

    print?

    1. // 注释:多字节包括GBK和UTF-8
    2. int GBK2UTF8(char *szGbk,char *szUtf8,int Len)
    3. {
    4. // 先将多字节GBK(CP_ACP或ANSI)转换成宽字符UTF-16
    5. // 得到转换后,所需要的内存字符数
    6. int n = MultiByteToWideChar(CP_ACP,0,szGbk,-1,NULL,0);
    7. // 字符数乘以 sizeof(WCHAR) 得到字节数
    8. WCHAR *str1 = new WCHAR[sizeof(WCHAR) * n];
    9. // 转换
    10. MultiByteToWideChar(CP_ACP,  // MultiByte的代码页Code Page
    11. 0,            //附加标志,与音标有关
    12. szGbk,        // 输入的GBK字符串
    13. -1,           // 输入字符串长度,-1表示由函数内部计算
    14. str1,         // 输出
    15. n             // 输出所需分配的内存
    16. );
    17. // 再将宽字符(UTF-16)转换多字节(UTF-8)
    18. n = WideCharToMultiByte(CP_UTF8, 0, str1, -1, NULL, 0, NULL, NULL);
    19. if (n > Len)
    20. {
    21. delete[]str1;
    22. return -1;
    23. }
    24. WideCharToMultiByte(CP_UTF8, 0, str1, -1, szUtf8, n, NULL, NULL);
    25. delete[]str1;
    26. str1 = NULL;
    27. return 0;
    28. }

    [cpp] view plain copy

    print?

    1. //UTF-8 GBK
    2. int UTF82GBK(char *szUtf8,char *szGbk,int Len)
    3. {
    4. int n = MultiByteToWideChar(CP_UTF8, 0, szUtf8, -1, NULL, 0);
    5. WCHAR * wszGBK = new WCHAR[sizeof(WCHAR) * n];
    6. memset(wszGBK, 0, sizeof(WCHAR) * n);
    7. MultiByteToWideChar(CP_UTF8, 0,szUtf8,-1, wszGBK, n);
    8. n = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);
    9. if (n > Len)
    10. {
    11. delete[]wszGBK;
    12. return -1;
    13. }
    14. WideCharToMultiByte(CP_ACP,0, wszGBK, -1, szGbk, n, NULL, NULL);
    15. delete[]wszGBK;
    16. wszGBK = NULL;
    17. return 0;
    18. }

    19. 附ASCII码图表

时间: 2024-10-13 12:36:47

Windows程序员必须知道的字符编码和字符集的相关文章

windows程序员C/C++转向linux程序员时,如何编写、调试linux程序

windows程序员使用vs或windbg进行调试相当熟悉,转到linux下面,要进行程序的编写.调试,往往非常痛苦(或者说不习惯吧).目前可以找到的各种IDE或编辑软件相当多,我试过的有eclipse+cdt+gdb,codeblock+gdb,vi+cgdb,都是不太理想,时不时的想往vs上靠,一直还是有vs的情结. 某日,正在查找gdb如何显示当前进程加载的动态库时,查到了visualgdb中关于gdb的教程,此时猛然想起了visualgdb这个工具(原来在用visualddk的时候瞧见过

做10年Windows程序员与做10年Linux程序员的区别

如果一个程序员从来没有在linux,unix下开发过程序,一直在windows下面开发程序, 同样是工作10年, 大部分情况下与在linux,unix下面开发10年的程序员水平会差别很大.我写这篇文章并不是想贬低windows下面开发的人,做windows开发的人看了可能会感觉不舒服,我并不是这个意思,我只是说说我自己的感受,我最早开始学习编程也是在windows下面的, 学的是VB,后来转到VC++,当时用的是VC6.0, 做windows下面的开发5年后转入linux下面做开发的,开始在li

做10年Windows程序员与做10年Linux程序员的区别(附无数评论)(开源软件相当于熟读唐诗三百首,不会作诗也会吟)

如果一个程序员从来没有在linux,unix下开发过程序,一直在windows下面开发程序, 同样是工作10年, 大部分情况下与在linux,unix下面开发10年的程序员水平会差别很大.我写这篇文章并不是想贬低windows下面开发的人,做windows开发的人看了可能会感觉不舒服,我并不是这个意思,我只是说说我自己的感受,我最早开始学习编程也是在windows下面的, 学的是VB,后来转到VC++,当时用的是VC6.0, 做windows下面的开发5年后转入linux下面做开发的,开始在li

字符编码与字符集

我们先弄清几个英文缩写: ASCII(American Standard Code for Information Interchange):美国标准信息交换代码 ISO (International Organization for Standardization):国际标准化组织 UCS(Universal Multiple-Octet Coded Character Set):通用多八位编码字符集,俗称UNICODE UTF(UCS Transformation Format):UNICO

字符编码详解

每一个程序员都不可避免的遇到字符编码的问题,特别是做Web开发的程序员,“乱码问题”一直是让人头疼的问题,也许您已经很少遇到“乱码”问题,然而,对解决乱码的方法的内在原理,您是否明白?本人作为一个程序员,在字符编码方面同样遇到不少问题,而且一直对各种编码懵懵懂懂.不清不楚:在工作中也曾经遇到一个很烦人的编码问题.这两天在网上收集了大量编码方面的资料,对字符编码算是理解的比较清楚了.下面把我认为比较重要的知识点记录下来,一方面方便以后复习:另一方面也希望给跟我一样懵懵懂懂的人一个参考.不对或不妥之

字符编码详解——彻底理解掌握编码知识,“乱码”不复存在

每一个程序员都不可避免的遇到字符编码的问题,特别是做Web开发的程序员,"乱码问题"一直是让人头疼的问题,也许您已经很少遇到"乱码"问题,然而,对解决乱码的方法的内在原理,您是否明白?本人作为一个程序员,在字符编码方面同样遇到不少问题,而且一直对各种编码懵懵懂懂.不清不楚:在工作中也曾经遇到一个很烦人的编码问题.这两天在网上收集了大量编码方面的资料,对字符编码算是理解的比较清楚了.下面把我认为比较重要的知识点记录下来,一方面方便以后复习:另一方面也希望给跟我一样懵懵

刨根究底字符编码之二——关键术语解释(下)

关键术语解释(下) 一.第1层 抽象字符表ACR (Abstract Character Repertoire抽象字符清单):明确字符的范围(即确定支持哪些字符) 1. 抽象字符表ACR是一个编码系统支持的所有抽象字符的集合,可以简单理解为无序的字符集合,用于确定字符的范围,即要支持哪些字符. 抽象字符表ACR的一个重要特点是字符的无序性,即其中的字符并没有编排数字顺序,当然也就没有数字编号. 2. "抽象"字符不具有某种特定的字形,不应与具有某种特定字形的"具体"

每一个程序员必须掌握的知识,字符集与字符编码.

1. 基础知识 计算机中储存的信息都是用二进制数表示的:而我们在屏幕上看到的英文.汉字等字符是二进制数转换之后的结果.通俗的说,按照何种规则将字符存储在计算机中,如'a'用什么表示,称为"编码":反之,将存储在计算机中的二进制数解析显示出来,称为"解码",如同密码学中的加密和解密.在解码过程中,如果使用了错误的解码规则,则导致'a'解析成'b'或者乱码. 字符集(Charset):是一个系统支持的所有抽象字符的集合.字符是各种文字和符号的总称,包括各国家文字.标点符

为什么国外程序员爱用 Mac?

from http://www.vpsee.com/2009/06/why-programmers-love-mac/ Mac 在国外很受欢迎,尤其是在 设计/web开发/IT 人员圈子里.普通用户喜欢 Mac 可以理解,毕竟 Mac 设计美观,简单好用,没有病毒.那么为什么专业人士也对 Mac 情有独钟呢?从个人使用经验来看我想有下面几个原因: 1.Mac OS X 是基于 Unix 的.这一点太重要了,尤其是对开发人员,至少对于我来说很重要,这意味着Unix 下一堆好用的工具都可以随手捡到.