1、什么是字符?
从显示的角度来说,字符可以理解成就是我们需要显示的单一实体。包括,数字6,字母5,中文“好”等等。
对字符的其它名词解释:
字符(Character)是文字与符号的总称,包括文字、图形符号、数学符号等。
2、什么是字符集?
一组字符的集合就是字符集。
字符集常常和一种具体的语言文字对应起来,该文字中的所有字符或者大部分常用字符就构成了该文字的字符集,比如英文字符集。
一组有共同特征的字符也可以组成字符集,比如繁体汉字字符集、日文汉字字符集。
比如,我们经常使用的简体中文,这么多个常用汉字组合在一起就是简体中文字符集。
3、为什么需要对字符进行编码?
能让计算机使用的数据0和1表示出字符集中的绝大部分或者全部字符,这就是字符编码。
另外一种解释:计算机要处理各种字符,就需要将字符和二进制内码对应起来,这种对应关系就是字符编码(Encoding)。
4、常见字符编码对应的二进制数据形式如下:
注:使用记事本保存文件得到的数据。
字符“abc”的ANSI编码对应的二进制形式:
中文字符“中国”的ANSI编码对应的二进制形式:
字符组合“a中国”的ANSI编码对应的二进制形式:
字符“abc”的Unicode编码(默认是小端法)对应的二进制形式:
注意:FFFE 仅仅是标记是何种编码,并不是编码的数据。
字符“abc”的Unicode大端法编码对应的二进制形式:
注意:FEFF 仅仅是标记是何种编码,并不是编码的数据。
字符“abc”的UTF8编码对应的二进制形式:
注意:EFBBBF仅仅是标记是何种编码,并不是编码的数据。
中文字符“中国”的Unicode编码对应的二进制形式:
中文字符“中国”的Unicode大端法编码对应的二进制形式:
中文字符“中国”的UTF8编码对应的二进制形式:
可以看得出来,不同编码格式对于相同字符对应的二进制形式是不完全一样的。
ANSI编码对于ASCII码字符是一个字节,对于中文字符是两个字节编码;
Unicode编码默认对于任何字符都是两个字节编码,有特殊情况;
UTF8编码对于ASCII码是采用一个字节,且与ANSI编码一致;对于中文字符是三个字节。
实际上,很多编码转换函数,就是把上面的数据进行相关的数学运算,得到预期编码格式的数据。
(注: 不好意思,上面这幅图中代码注释有错)
程序代码是将UTF8格式数据转换成Unicode格式(这里默认是UTF16LE格式)。
假设传入的是中文字符“周排行”的UTF8格式数据,如下:
E591A8E68E92E8A18C
周排行
转换得到的UTF16LE格式数据为:
685492634C88
周排行
5、C++源代码需要特定的编码格式吗?
操作系统环境:中文WindowsXPProfessinalSP2版本
编译器环境:VS2005
源代码格式:.cpp
源代码:
//中differentCodingStyle.cpp:定义控制台应用程序的入口点。
//
#include"stdafx.h"
#include<fstream>
usingnamespacestd;
int_tmain(intargc,_TCHAR*argv[])
{
istreaminfile;
ostreamoutfile;
return0;
}
源代码对应的二进制形式:
从另存为的选项中可以看出默认编码方式是GB2312.
经测试,同样可以把源代码的编码格式改为别的,如UTF8等,在上面的环境下编译一样可以通过。(注:在不同环境可能会有编译不通过的)。
6、ANSI编码是什么?
ANSI编码是不同国家和地区根据当地使用的字符集进行本地化的一种编码方式。如在简体中文系统下,ANSI编码就是GB2312编码;在日文系统下,ANSI编码就是JIS编码;而对于纯英文系统ANSI编码就是ASCII编码。
7、Unicode是字符集还是编码格式?
Unicode是一种字符集,是包含基本上所有字符的字符集。但是很多情况下,很多人把它又当作一种编码格式的名称,正如记事本程序一样:
每种字符集都会对应于至少一种编码方式。Unicode字符集的编码格式有:
UTF8
UTF16LE:UTF16小端法(两个字节表示一个字符,自然有大端小端之说)
UTF16BE:UTF16大端法
UTF7
……
也可以理解,把Unicode称为编码格式的一种,也许就是因为Unicode默认是两字节一个字符,UTF16正是两个字节一个字符,所以Unicode也就这么叫了。
8、Unicode和UTF是什么关系?
实现Unicode字符集的编码方式即被称为Unicode转换格式,即UnicodeTranslationFormat,简写为UTF.
9、对于UTF8、UTF16等编码格式的字符串数据,C程序中是使用char*来指向它们所在的缓冲区还是用wchar_t*,或者用更复杂的格式?
char*表示字符串时是用于表示以0结束的字符串。在仅仅表示ASCII码字符的时候很有用。
UTF8中ASCII码字符和ANSI的ASCII码字符一致,所以用char*也可以,中文字符使用的是三个字节的数据,每个字节都不能出现0,所以用char*表示UTF8编码的数据至少在有字母和中文的组合字符串中不会因为遇到字符0而提前截断字符串的出错。
而对于UTF16,用char*就很危险。因为,字母A用UTF16的编码格式就是4100或者0041.(十六进制形式;小端或者大端法表现为上面这两种形式),char*在遇到00的时候会提前截断字符串,所以上面的函数UTF_8ToUnicode的第一个参数是wchar_t*pOut,也是考虑到这种情况的。
MultiByteToWideChar函数和WideCharToMultiByte函数类似分析。
更复杂的格式根据需要采用,比如指针指向四个字节等等。
参考网址:
1、字符:http://zh.wikipedia.org/wiki/%E5%AD%97%E7%AC%A6
2、字符编码:http://zh.wikipedia.org/wiki/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81
3、深入了解字符集和编码问题::http://webcenter.hit.edu.cn/articles/2009/04-01/04193356.htm
4、Unicode:http://zh.wikipedia.org/zh-cn/Unicode
5、GB2312编码:http://zh.wikipedia.org/zh-cn/GB2312
6、字符编码:http://man.chinaunix.net/tech/secure_programs_howto_cn/x439.html
7、字符,字节和编码:http://www.regexlab.com/zh/encoding.htm
8、字符编码详解及由来(UNICODE,UTF-8,GBK)[转帖]:http://203.208.37.132/search?q=cache:hVhX6clwkGkJ:www.phpweblog.net/fuyongjie/archive/2009/03/11/6374.html+UTF8+Unicode&cd=7&hl=zh-CN&ct=clnk&gl=cn&st_usg=ALhdy2_IZvBGmV9xgIOKUbDSXGpU4Z4E8g
9、字符编解码的故事(ASCII,ANSI,Unicode,Utf-8):http://www.cnblogs.com/KevinYang/archive/2009/01/31/1381570.html
10、Ansi、Unicode、UTF8字符串之间的转换和写入文本文件:http://www.cppblog.com/greatws/archive/2009/01/16/60546.html
11、UTF-8andUnicodeFAQ:http://www.linuxforum.net/books/UTF-8-Unicode.html
12、Unicode和UTF-8之间的转换详解:http://hi.baidu.com/dustin_xiao/blog/item/2ab75b24c27ca32ed507426f.html