C语言处理汉字转
在处理套打程序时用到TextOut,但TextOut无法自动换行,只好动手写
代码,可是处理到汉字部分时卡住了,搜索网上判断汉字的帖子,都语焉不详,经过一下午的研究,终于整理出一个简单的教程。其实判断汉字的代码很简单,简单到只有一行就可以了,但不理解汉字编码的基础,这一行代码却万万无法
理解。常用的字符编码有以下三种:1、ASCII只支持英文,全部为8位2、DBCS支持英文和中文,但中文需要两个字节(16位)3、UNICODE支持英文和中文,英文和中文都需要两个字节ASCII是DOS时代的,无法支持中文。DBCS是Win9x支持的字符集。UNICODE是win2k和xp支持的字符集。而汉字的编码目
前有GB2312-1980和GB18030-2000,GB2312就是DBCS类型的汉字编码,
GB18030就是UNICODE的汉字编码,当然GB18030兼容GB2312,也就是说
GB18030也支持DBCS的字符处理方式。虽然GB18030是2000年后强制执行的
国家标准,但目前使用最多的还是GB2312编码,而且GB2312也足够处理你所
用到的汉字了。还有GBK编码是GB2312的增强版。这里我仅支持GB2312。由
于GB2312是中国大陆制定的标准,所以繁体中文并不在GB2312的编码中,如
果你的程序需要支持繁体中文,则还需要处理Big5编码。其实也很简单。下面
说一下在C中如何处理GB2312编码的汉字。以VC6.0为例,如果声明变量的类
型为wchar_t则是UNICODE编码,如果是char则是DBCS编码比如我的一个函
数声明是:void Justify(HDC hdc,PTSTR pText,RECT*prc,int iAlign)其中的pText是PTSTR类型,PTSTR在WINNT.H中有两个定义(WINNT.H中的这段代码
我删掉了中间无关的部分)#ifdef UNICODE typedef LPWSTR PTSTR,LPTSTR;//
如果是UNICODE编码,则定义PTSTR为LPWSTR类型#else typedef LPSTR PTSTR,LPTSTR;//如果是不是UNICODE编码,则定义PTSTR为LPSTR类型
#endif LPSTR定义为CHAR的指针LPSWSTR定义为WCHAR的指针CHAR定义为
char类型WCHAR定义为wchar_t类型而wchar_t定义为unsigned short类型,它是16位,两个字节,无
符号短整数是UNICODE还是非UNICODE取决于你的编
译选项,如果在[工程]-[选项]-[C/C++]的[预处理程序定义]中填入了_UNICODE,那么程序会用wchar_t指针来定义LPSTR,如果没有_UNICODE,那么程序会用char指针来定义LPSTR,这样带来的区别就是,你接受到的pText中的字节内
容是不一样的,[i服了you]这个字串如果在没有定义_UNICODE的情况下,是8
个字节,而在定义了_UNICODE的情况下是12个字节。反映到程序中就是,如
果没有定义_UNICODE,那么就要把英文字符当成1个字节来处理,而汉字字符c语言搜题软件推荐
的编码是采用GB2312编码规范来的;如果定义了_UNICODE,那么英文字符要当
成2个字节来处理,而汉字字符的编码是采用UNICODE编码来的。举例来说,win98不采用UNICODE编码而采用的是DBCS编码,为了让我的程序既可以在XP
下运行又可以在Win98下运行,我没有定义_UNICODE。这样我的程序代码就要
把字符串当成DBCS编码来处理,也就是英文字符是1个字节,中文字符是2个
字节,中文编码采用GB2312编码。用Justify来说明:我给pText传递来[你]
这个汉字,那么pText应该有两个字节来存放[你]这个字,设置段点来读一下pText的内容。void Justify(HDC hdc,PTSTR pText,RECT*prc,int
iAlign){static TCHAR szText={TEXT("你")};pText=szText;}设断调试会发
现*pText=-60,怎么会这样呢,原因是没有按unsigned char来转换*pText的值,修改代码如下:void Justify(HDC hdc,PTSTR pText,RECT*prc,int iAlign){static TCHAR szText={TEXT("你")};unsigned char sqChar[20];
//这个变量就是为了强制转换类型用的pText=szText;sqChar[0]=*pText;sqChar[1]=*(pText+1);}这时下断查看sqChar[0]=196,sqChar[1]=227就对了,为什么呢,因为它和GB2312的编码是一样的。GB2312-80编码的编码范围是高
位0xa1-0xfe,低位是0xa1-0xfe,其中汉字范围为0xb0a1和0xf7fe,如果只
是简单地判断汉字,则只要查看高字节是否大于等于0xa1就可以了,还有就是,全角字符的高字节统统等于0xa3,所以很容易可以区别出全角字符来。如果你
希望你的程序能支持到GB18030,那么就去GB18030的规范来看看。网上有
很多判断汉字的说法,你只要记住,你要支持的编码是哪个?GB2312、GBK、
GB18030?每个编码有自己的编码范围或者规范,网上之所以有不同的说法,正
是因为他们互相说的不是同一种编码方式。我这里说的是GB2312的编码,如果
你的程序要编译成支持UNICODE的话,那么这段代码就要修改成对应UNICODE
规范的代码了。附简单的测试汉字、全角字符、英文的程序://test.c//源代
码作者:夏克*************//新建Win32 Application工程,把test.c加入,运行,试着修改szText的值,来观察代码效果#include windows.h int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow){static TCHAR szText={TEXT("i服,了。uy")};PTSTR pText;int i;unsigned char sqChar[20];pText=szText;
while(*pText!='[message]'){i=IsGB(pText);switch(i){case 0:pText++;
MessageBox(NULL,TEXT("发现数字、英文字符或英文标点"),TEXT("Hello"),0);break;case 1:pText++;pText++;MessageBox(NULL,TEXT("发现全角字符"),TEXT("Hello"),0);break;case 2:pText++;pText++;
MessageBox(NULL,TEXT("发现汉字"),TEXT("Hello"),0);break;}}return 0;}int IsGB(PTSTR pText){unsigned char sqChar[20];sqChar[0]=*pText;if(sqChar[0]=0xa1)if(sqChar[0]==0xa3)return 1;//全角字符else return 2;//汉字else return 0;//英文、数字、英文标点}
汉字在电脑中的编码处理简介GB2312/GBK/GB18030/BIG5中文字符编码简
介GB2312/GBK/GB18030/BIG5 1GB2312-80 GB2312码是中华人民共和国国家汉
字信息交换用编码,全称《信息交换用汉字编码字符集--基本集》,由国家标
准总局发布,1981年5月1日实施,通行于大陆。新加坡等地也使用此编码。
GB2312收录简化汉字及符号、字母、日文假名等共7445个图形字符,其
中汉字占6763个。GB2312规定"对任意一个图形字符都采用两个字节表示,每
个字节均采用七位编码表示",习惯上称第一个字节为"高字节",第二个字节为"低字节"。
GB2312将代码表分为94个区,对应第一字节;每个区94个位,对应第二
字节,两个字节的值分别为区号值和位号值加32(2OH),因此也称为区位码。
01-09区为符号、数字区,16-87区为汉字区,10-15区、88-94区是有待进一
步标准化的空白区。GB2312将收录的汉字分成两级:第一级是常用汉字计3755个,置于16-55区,按汉语拼音字母/笔形顺序排列;第二级汉字是次常用汉字计3008个,置于56-87区,按部首/笔画顺序排列。故而GB2312最多能表示6763个汉字。
GB2312的编码范围为2121H-777EH,与ASCII有重叠,通行方法是将GB码两个字节的最高位置1以示区别。
2 GBK GB2312-80仅收汉字6763个,这大大少于现有汉字,随着时间推移
及汉字文化的不断延伸推广,有些原来很少用的字,现在变成了常用字,例如:的"镕"字,未收入GB2312-80,现在大陆的报业出刊只得使用(金+容)、(金容)、(左金右容)等来表示,形式不一而同,这使得表示、存储、输入、处
理都非常不方便,对于搜索引擎等软件的构造来说也不是好消息,而且这种表
示没有统一标准。从我们对人民日报98年数据的处理过程中,得出这样的经验:回填外字最困难的就是如何得到这种表示方法的集合。
为了解决这些问题,以及配合UNICODE的实施,全国信息技术化技术委员
会于1995年12月1日《汉字内码扩展规范》。GBK向下与GB2312完全兼容,
向上支持ISO 10646国际标准,在前者向后者过渡过程中起到的承上启下的作用。GBK亦采用双字节表示,总体编码范围为8140-FEFE之间,首字节在81-FE
之间,尾字节在40-FE之间,剔除XX7F一条线。
GBK共收入21886个汉字和图形符号,包括:
*GB2312中的全部汉字、非汉字符号。*BIG5中的全部汉字。*与ISO
10646相应的国家标准GB13000中的其它CJK汉字,以上合计20902个汉字。*
其它汉字、部首、符号,共计984个。
微软公司自Windows 95简体中文版开始支持GBK代码,但目前的多数搜索
引擎都不能很好地支持GBK汉字。
GBK编码区分三部分:
*汉字区包括GBK/2:OXBOA1-F7FE,收录GB2312汉字6763个,按原序排列;GBK/3:OX8140-AOFE,收录CJK汉字6080个;GBK/4:OXAA40-FEAO,收录CJK
汉字和增补的汉字8160个。*图形符号区包括GBK/1:OXA1A1-A9FE,除GB2312
的符号外,还增补了其它符号GBK/5:OXA840-A9AO,扩除非汉字区。*用户自
定义区即GBK区域中的空白区,用户可以自己定义字符。
3 GB18030 GB18030是最新的汉字编码字符集国家标准,向下兼容GBK和
GB2312标准。GB18030编码是一二四字节变长编码。一字节部分从0x0~0x7F与ASCII编码兼容。二字节部分,首字节从0x81~0xFE,尾字节从0x40~0x7E以及
0x80~0xFE,与GBK标准基本兼容。四字节部分,第一字节从0x81~0xFE,第二字
节从0x30~0x39,第三和第四字节的范围和前两个字节分别相同。四字节部分覆
盖了从0x0080开始,除去二字节部分已经覆盖的所有Unicode 3.1码位。也就
是说,GB18030编码在码位空间上做到了与Unicode标准一一对应,这一点与
UTF-8编码类似。
目前最新的glibc 2.2.x系列已经全面支持了GB18030 Locale和GB18030
与UCS-4之间的编码转换,也就是说在系统层上Linux已经可以支持GB18030标
准了。下面问题的关键就是怎样让XFree86窗口系统也支持GB18030标准。
4 BIG
5 BIG5是通行于台湾、香港地区的一个繁体字编码方案。虽然存在
一些瑕疵,但广泛应用于电脑行业,尤其是互联网中,从而成为一种事实上的
行业标准。
1983年10月,科学委员会、教育部国语推行委员会、中央标准局、行政院共同制定了《通用汉字标准交换码》,后经修订于1992年5月公布,更名为《中文标准交换码》,BIG5是台湾资讯工业策进会根据以上标准制定的
编码方案。
BIG5码是双字节编码方案,其中第一个字节的值在OXAO-OXFE之间,第二
个字节在OX40-OX7E和OXA1-OXFE之间。
BIG5收录13461个汉字和符号,包括:
*符号408个,编码位置A140-A3BE*常用字5401个,编码位置A440-C67E,包括台湾教育部颁布的《常用国字标准字体表》的全部汉字4808个,台湾教科
书常用字587个,异体字6个。*次常用字7652个,编码位置C940-F9D5,包括
台湾教育部颁布的《次常用国字标准字体表》的全部汉字6341个,《罕用国字
标准字体表》中使用频率较高的字1311个。
来自:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论