基于C#字符编码的探讨

来源 :计算机光盘软件与应用 | 被引量 : 0次 | 上传用户:baoxiongwen
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘要:在C#中,将字符串视为对象,关键字string本身是一种引用类型,在底层则对应到String类,在NET教程的描述中,String类的编码通常认为是Unicode,但在实际使用过程中,如果不去注意字符编码格式,则会在显示字符时出现乱码的现象,本文的目的就是来探讨C#中字符的编码格式,以及如何在编码之间进行转换。
  关键词:C#字符;编码;探讨
  中图分类号:TP312.1文献标识码:A文章编号:1007-9599 (2010) 15-0000-02
  Based on the Character Encoding of C#
  Wu Hao1,2
  (1.University Institute of Computer Science and Technology,Suzhou215006,China;2.Mudu High School,Suzhou City,Jiangsu Province,Suzhou215101,China)
  Abstract:In C#,the string as an object,the keyword string itself is a reference type,at the bottom corresponds to the String class,the description in the NET tutorial,String encoding the class generally considered to be Unicode,but in practice Use,if they do not pay attention to character encoding format,will be garbled characters in the display phenomenon,the purpose of this paper is to explore the characters in C# code format,and how to convert between the encoding.
  Keywords:C# character;Coding;Of
  在编写程序时如果要在内存、文件或电子邮件中读取一个字符串,那么应该知道它是使用什么编码方案,否则就不能将它正确的解释或显示给用户。如果没有正确获得对应的编码格式,那么在具体显示或打印等输出字符的时候会发现有乱码的现象,这时首先要判断是不是我们解释用的编码方式出错了。在很多的C#教程中在讲解String类时,都认为String类的编码是Unicode,从流中读取字符串时,给出的演示代码都是将编码设定为System.Text.Encoding.Default,这种方式在很多情况下都能获得正确的字符串内容,但这时就无从得知其具体采用的是何种编码了。并且也不是所有情况下,使用System.Text.Encoding.Default都能正常的显示字符。以下是我在C#编程环境下对字符编码格式的一个简单探讨:
  一、字符编码的格式
  我们最早学习到的字符编码应该是美国上世纪60年代制定的ASCII码,在这套编码中,规定了英语字符和二进制编码的一一对应关系,每个字符对应到7位二进制编码,字节中的最高位置0,这样最多能表示128个字符,英语字符使用ASCII码是足够了,但世界上很多国家的文字都要比英语字符复杂的多,每种语言都可以设定一组对应的二进制编码,如欧洲国家的字符则是将一个字节中的全部8位二进制位都用上,这样可以最多表示256个字符,而GB2312编码的汉字则在计算机中占用2个字节的存储空间,以下是ASCII码和GB2312编码存储方式的详细介绍:
  (一)ASCII码,ASCII码一共规定了128个字符的编码,比如空格“SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0,所以ASCII码只需一位字节保存。
  (二)GB2312,简体中文常见的编码方式是GB2312,使用两个字节表示一个汉字,所以理论上最多可以表示256x256=65536个符号。gb2312编码使用的是区位码寻字方式,1-9区存放中文符号,16-55区存放一级汉字,56-87区存放二级汉字,如第1个汉字位于16区的第1位,为:‘啊’,所以1601,即0x1001就代表了该‘啊’的区位码值。
  这样就带来了一个问题:比如说有两个字节的空间来存放字符,如何去知道这两个字节是表示两个字母还是一个汉字或者是其他的符号呢?或者说,有没有一种编码方案,可以囊括世界上各种语言和字符?如果有,假设最复杂的字符需要4个字节去表示,那是不是一个英语字符也要用4个字节表示呢,这样岂不是造成空间上的巨大浪费?事实上,这种基本囊括所有字符的编码方案就是Unicode,但Unicode只是规定了对应字符的二进制编码表示,并没有规定二进制编码在计算机内如何存储,为了同时解决从字节中读取字符时的疑义和节省存储空间,就产生了UTF8编码,这是互联网上使用最广的一种Unicode实现方式。
  UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1-4个字节表示一个符号,根据不同的符号而变化字节长度。UTF-8的编码规则很简单,只有二条:1、对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。2、对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
  二、Unicode和UTF8的关系
  以下是Unicode和UTF-8之间的转换关系表:
  U-00000000-U-0000007F:0xxxxxxx //没有1表示只有1个字节
  U-00000080-U-000007FF:110xxxxx 10xxxxxx//前面2个1表示由2个字节
  U-00000800-U-0000FFFF:1110xxxx 10xxxxxx 10xxxxxx //前面3个1表示由3个字节
  U-00010000-U-001FFFFF:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx //依次类推
  U-00200000-U-03FFFFFF:111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  U-04000000-U-7FFFFFFF:1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
  xxx的位置由字符编码数的二进制表示的位填入,越靠右的x具有越少的特殊意义,只用最短的那个足够表达一个字符编码数的多字节串,注意在多字节串中,第一个字节的开头“1”的数目就是整个串中字节的数目,如果字节的第一位是0,则这个字节就表示一个字符,相当于ASCII码,其他情况下不论是多少字节的字符,字节的第一位全为1,要判断这个字符有多少字节,只要看首字节中1的数量,比如首字节中前4位全为1,第五位是0,则这个字符应该是由4个字节表示。Unicode编码转换到UTF-8,简单的把Unicode字节流套到x中就变成UTF-8了。
  三、实际编程时需注意的问题
  从以上的资料可以看出,在Unicode和UTF8之间存在着线性转换的关系,因此可以通过一个规则的转换过程来实现处理UTF8编码的字节流到Unicode,unicode对汉字进行了重新编码,这和gb2312编码的方式和顺序完全不同,unicode对汉字编码从0x4E00开始,到0x9FA5为止,所以unicode和gb2312编码的转换,就需要一个转换对照表,实现快速转换,在简体中文的操作系统中,使用System.Text.Encoding.Default和Encoding.GetEncoding.(“GB2312”)效果是一样的,即System.Text.Encoding.Default会自动获得系统当前编码。但是如果是繁体中文环境再去用Default去读取包含简体中文字符串信息的字节流,就会出现乱码。
  综上所述,.NET中的String确实只有Unicode一种。关注编码格式应该是在byte[]到string的过程,转换成String对象后它以后的编码格式就是unicode,再去讨论其编码就没有意义了。
  参考文献:
  [1]Nagel,Christian/Evjen,Bill/Glynn,Jay/Watson,Karli/Skinner,Morgan.Professional C# 2005 With.Net 3.0[M].John Wiley & Sons Inc,2007
  [2]李继攀.程序天下——Visual C#2008开发技术实例详解[M].北京:电子工业出版社,2008
其他文献
文章从信函分拣人机结合生产作业流程的优化目的出发,利用定量的计算方法,对其工艺流程、设备配置、场地布局、作业组织、人员配备、分拣程序设计诸方面进行了分析;通过定性、定
添加简单的点击音效到按扭中你会让你的Flash作品有不样的感觉的。想尝试一下?为什么不看看这里的Beat Suite音频文件?这34种Flash音效有各式各样的声音。Beat Suite专门为多媒
针对开关磁阻电机(SRM)双凸极结构引起的铁心磁场复杂和铁损计算难以实现的问题,开展了SRM铁损计算方法的研究,对电机铁损与铁心磁密正交分量之间的关系进行了分析,根据铁心损
意大利邮政公司董事会不久前公布了2006~2008邮政发展规划。其发展目标包括在未来三年中总营业额达到103.8亿欧元,增长3.5%;纳税及付息前收益(EBIT)增长10%,达到12亿欧元;纳税、付息、折
推进机制转换加快邮政发展上海市邮政局局长吴一帆回顾“八五”所走过的历程,上海邮政的发展及其效益虽不能与电信同日而语,但亦取得了长足的进步。邮政发展的投入资金逐年加大
在图片中添加金属和墨水效果的方法有好几种,但正如Research Stucios的Jeff Knowles在这里展示的,在通道中添加额外的金属Pantone图层可以让这个过程更快捷。
一直严守秘密的S10于2006年9月26日在北京星光现场正式暴光。S10的别开生面的暴光形式,让现场的新有观众都感到特别的惊奇和震撼。Soul+Slim+style+Surprise=S10这三个英文词语全
针对纯电动汽车起步的关键问题即电机输出转矩控制,对纯电动汽车起步加速过程进行了动力学分析,依据加速踏板开度和开度变化率,运用模糊控制原理解析了驾驶员的起步意图,根据
2002年初邮政电子汇兑系统的正式投入运行是中国邮政发展史上的一件大事.邮政电子汇兑系统能够彻底解决邮政汇兑的传递时限问题、提高了服务质量;能够实现汇款传递的无纸传输
易拉罐开始往下落,并最终躺在水沟里不再动的时候,镜头从慢动作转变到了时间推移,刚开始,当停机坪有了明显的变化而周围的植物也不断枯荣时,易拉罐依然没有变化。