字符编码
字符编码笔记:ASCII,Unicode和UTF-8
http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html
字符编码详解
http://www.crifan.com/files/doc/docbook/char_encoding/release/html/char_encoding.html
ANSI编码和Unicode编码的不同
http://blog.csdn.net/chaijunkun/article/details/4654397
字符,字节和编码
http://www.regexlab.com/zh/encoding.htm
1.1 字符与编码的发展
从计算机对多国语言的支持角度看,大致可以分为三个阶段:
| 系统内码 | 说明 | 系统 | |
| 阶段一 | ASCII | 计算机刚开始只支持英语,其它语言不能够在计算机上存储和显示。 | 英文 DOS |
| 阶段二 | ANSI编码 (本地化) |
为使计算机支持更多语言,通常使用 0x80~0xFF 范围的 2 个字节来表示 1 个字符。比如:汉字 '中' 在中文操作系统中,使用 [0xD6,0xD0] 这两个字节存储。 不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS 等各自的编码标准。这些使用 2 个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI 编码。在简体中文系统下,ANSI 编码代表 GB2312 编码,在日文操作系统下,ANSI 编码代表 JIS 编码。 不同 ANSI 编码之间互不兼容,当信息在国际间交流时,无法将属于两种语言的文字,存储在同一段 ANSI 编码的文本中。(不可将中文与日文放在同一个字符串中,但中文和英文可以,因为中文编码包含了英文字符。) |
中文 DOS,中文 Windows 95/98,日文 Windows 95/98 |
| 阶段三 | UNICODE (国际化) |
为了使国际间信息交流更加方便,国际组织制定了 UNICODE 字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,以满足跨语言、跨平台进行文本转换、处理的要求。 | Windows NT/2000/XP,Linux,Java |
1.2 字符,字节,字符串
理解编码的关键,是要把字符的概念和字节的概念理解准确。这两个概念容易混淆,我们在此做一下区分:
| 概念描述 | 举例 | |
| 字符 | 人们使用的记号,抽象意义上的一个符号。 | '1', '中', 'a', '$', '¥', …… |
| 字节 | 计算机中存储数据的单元,一个8位的二进制数,是一个很具体的存储空间。 | 0x01, 0x45, 0xFA, …… |
| ANSI 字符串 |
在内存中,如果“字符”是以 ANSI 编码形式存在的,一个字符可能使用一个字节或多个字节来表示,那么我们称这种字符串为 ANSI 字符串或者多字节字符串。 | "中文123" (占7字节) |
| UNICODE 字符串 |
在内存中,如果“字符”是以在 UNICODE 中的序号存在的,那么我们称这种字符串为 UNICODE 字符串或者宽字节字符串。 | L"中文123" (占10字节) |
由于不同 ANSI 编码所规定的标准是不相同的,因此,对于一个给定的多字节字符串,我们必须知道它采用的是哪一种编码规则,才能够知道它包含了哪些“字符”。而对于 UNICODE 字符串来说,不管在什么环境下,它所代表的“字符”内容总是不变的。
2.1 程序中的字符与字节
在 C++ 和 Java 中,用来代表“字符”和“字节”的数据类型,以及进行编码的方法:
| 类型或操作 | C++ | Java |
| 字符 | wchar_t | char |
| 字节 | char | byte |
| ANSI 字符串 | char[] | byte[] |
| UNICODE 字符串 | wchar_t[] | String |
| 字节串→字符串 | mbstowcs(), MultiByteToWideChar() | string = new String(bytes, "encoding") |
| 字符串→字节串 | wcstombs(), WideCharToMultiByte() | bytes = string.getBytes("encoding") |
以上需要注意几点:
- Java 中的 char 代表一个“UNICODE 字符(宽字节字符)”,而 C++ 中的 char 代表一个字节。
- MultiByteToWideChar() 和 WideCharToMultiByte() 是 Windows API 函数。
- mbstowcs(), MultiByteToWideChar()/wcstombs(), WideCharToMultiByte()就是在ANSI字符串与UNICODE字符串之间相互转换。为什么要转换?以"中文123"为例,因为以ANSI字符串编码,其长度为7字节,以UNICODE字符串编码,其长度为10字节。
2.1 C++ 中相关实现方法
以上需要注意 #pragma setlocale 与 setlocale(LC_ALL, "") 的作用是不同的,#pragma setlocale 在编译时起作用,setlocale() 在运行时起作用。
浙公网安备 33010602011771号