注:在文章中所有引用的内容都是列出引用链接,希望大家也都能有保护知识产权的意识,毕竟大家都是coder,一砖一瓦都是自己的心血,别人已经给我们分享了,难道还要据为己有。
在代码的实际编写过程中,总会遇到字符集的问题,之前出问题的时候直接搜一下,结果就出来了,后来想说还是总结一下吧,老是半懂不懂的感觉实在太难受了。
其实字符集的定义大家都明白,但是这里还是要简单提一下。
字符的表示是由字符集charset及该字符集的编码决定。
1.ASCII(又称ASCII 127) 只有一种编码
2.ANSI字符集 又称MBCS(MultiBytes Character System),主要是各个国家自己扩展自ASCII的字符集。
3.UNICOUDE 有三种编码方式 UTF-8, UTF-16,UTF-32
这些都是我一直知道的,但是为什么我还是经常在coding的时候犯一些这方面的错误呢?
我仔细想了一下,应该有两个原因:
1.知道有这些字符集,但是不求甚解,不知道具体是怎么编码的,不知道之间的区别,当然在用的时候就会产生疑惑;
2.在具体coding的时候,对平台以及相应的API、数据类型也不明白,也会出现接口错用的问题。
那么,我就从这两方面好好探讨一下。
字符集及编码
1.ASCII
ASCII是基于拉丁字母的一套编码系统,主要用于显示英语及其它西欧语言,是当今最流行的单字节编码系统。
ASCII用7bit表示字符,第一位用作校验位,EASCII用8bit表示,用于表示一些特殊字符。
明显用来表示汉语是不可能的,当然人家老外最开始还没想那么远。
如果有可能的话,希望大家还是熟悉一些ASCII编码,有时候一些笔试题就会涉及到大小写切换啊这类的,当然题目不可能这么简单,但是它又不会告诉你大小写编码值 差多少,这种情况下就比较尴尬了。
2.MBCS
有人理解MBCS是这么一种编码,leading byte>127就采用双字节,leading byte<127就采用ASCII编码。
其实上面的理解有一点点偏差,即leading byte>127的时候,编码该字符可能是两个字节,也可能是三个字节。有些特殊字符确实是需要用到三个字节来表示的。
3.UNICODE
标准一乱,ISO就要出场了,ISO说我给你们光明,于是就有了UNICODE,UNICODE也叫宽字符集。
有人说,UNICODE不就是固定死要两字节编码吗?
标准当然要比这个复杂,至于复杂也是有原因的,可以看着标准自己琢磨(orz)。
EF BB BF | UTF-8 |
FE FF | UTF-16/UCS-2, little endian |
FF FE | UTF-16/UCS-2, big endian |
FF FE 00 00 | UTF-32/UCS-4, little endian |
00 00 FE FF | UTF-32/UCS-4, big endian |
三种编码规则中UTF-16/UTF-32都很好理解,就是定长2字节或4字节,最复杂的算是UTF-8,,说它复杂是因为它是变长编码标准。在实际的使用中,我们最常用到的是UTF-16,但此处也让我们理解一下UTF-8这个特殊的家伙。
UTF-8是同时兼顾编码效率以及覆盖面而提出的。
UTF-8编码字节含义:
对于UTF-8编码中的任意字节B,如果B的第一位为0,则B为ASCII码,并且B独立的表示一个字符;
如果B的第一位为1,第二位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的一个字节,并且不为字符的第一个字节编码;
如果B的前两位为1,第三位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由两个字节表示;
如果B的前三位为1,第四位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由三个字节表示;
如果B的前四位为1,第五位为0,则B为一个非ASCII字符(该字符由多个字节表示)中的第一个字节,并且该字符由四个字节表示;
平台及API
了解了上面的知识,有助于我们在coding的过程中思路更加清晰。其实有时候我也在想,标准的统一性和编码效率到底哪一个更重要?如果让我个人选择的话,我可能会选择标准的统一性,特别是现在的平台越来越多,差异性越来越大的情况下,统一的标准显得尤其重要。
VS工具支持MBCS及UNICODE字符集。那么我们在windows平台上开发软件时应该注意什么呢?
(1)windows内置了数据类型WCHAR代表宽字符,但是当我们不关系到底采用哪种字符集的时候,我们可以用TEXT来让编译器自己选择到底是UNICODE还是ASCII。
(2)ascii专用的函数及数据类型,比如strlen,LPSTR,都需要改成wcstrlen,LPTSTR
(3)从windows NT开始,windows内核就是UNICODE内建的,因此UNICODE的效率比ASCII高
(4)在表示字符串常量的时候,不能“abc” (ascii) ,也不能L"abc"(unicode),而最好是T("abc")(让编译器自己选择)
(5)MBCS和UNICODE之间的字符转换:WideCharToMultiByte MultiByteToWideChar 不过这两个函数对我们没什么用处,我们应该做到程序中“没有”ASCII 和UNICODE。
(6)str与wcs前缀都是标准c函数,需要标准C库才能运行,而lstr前缀是windows提供的原生函数,不需要C运行库。
关于字符集,并没有在linux平台上尝试过。
借鉴的内容地址:
http://www.cnblogs.com/chrisfang6/articles/1862751.html
http://blog.163.com/hbu_lijian/blog/static/1261291532013031101757468/