汉字字符集

来源:互联网 发布:食品安全软件 编辑:程序博客网 时间:2024/05/06 13:24

1简介

1.1 gb2312字符集

    GB2312 是汉字字符集和编码的代号,中文全称为“信息交换用汉字编码字符集”,由中华人民共和国国家标准总局发布,一九八一年五月一日实施。GB 是“国标” 二字的汉语拼音缩写。GB2312 字符集 (character set) 只收录简化字汉字,以及一般常用字母和符号, 主要通行于中国大陆地区和新加坡等地。GB2312 共收录有 7445 个字符,其中简化汉字 6763 个,字母和符号 682 个。GB2312 将所收录的字符分为 94 个区,编号为 01 区至 94 区;每个区收录 94 个字符,编号为 01 位至 94 位。GB2312 的每一个字符都由与其唯一对应的区号 和位号所确定。例如:汉字“啊”,编号为 16 区 01 位。

GB2312 字符集的区位分布表:

  区号    字数    字符类别    01      94    一般符号    02      72    顺序号码    03      94    拉丁字母    04      83    日文假名    05      86    Katakana    06      48    希腊字母    07      66    俄文字母    08      63    汉语拼音符号    09      76    图形符号 10-15            备用区 16-55    3755    一级汉字,以拼音为序 56-87    3008    二级汉字,以笔划为序 88-94            备用区

这本手册列出了 GB2312 的全部字符和它们的区位号。

GB2312 编码

GB2312 原始编码 (encoding) 是对所收录的每个字符都用两个字节 (byte) 表示。 第一字节为“高字节”,由字符的区号值加上 32 而形成;第二字节为“低字节”, 由字符的位号值加上 32 而形成。例如:汉字“啊”,编号为 16 区 01 位。它的 高字节为 16 + 32 = 48 (0x30),低字节为 01 + 32 = 33 (0x21),合并而成的编 码为 0x3021。

在区位号值上加 32 的原因大慨是为了避开低值字节区间。

由于 GB2312 原始编码与 ASCII 编码的字节有重叠,现在通行的 GB2312 编码是 在原始编码的两个字节上各加 128 修改而形成。例如:汉字“啊”,编号为 16 区 01 位。它的原始编码为 0x3021,通行编码为 0xB0A1。

如果不另加说明,GB2312 常指这种修改过的编码。

GB2312 与 Unicode 的关系

GB2312 字符集是 Unicode 字符集的一个子集。这也就是说,GB2312 所收录的每 一个字符都收录在 Unicode 之中。

但是 GB2312 编码和 Unicode 编码确没有什么相同之处。同一个汉字,它的 GB2312 编码和 Unicode 编码确毫不相同。例如:汉字“啊”,它的 GB2312 编码为 0xB0A1,但是它的 Unicode 编码为 0x554A。

1.2 GBK编码

     GBK,全称《汉字内码扩张规范》(GBK即国标,扩展汉语拼音缩写,英文Chinese Internal Code Specification)。它包含2万个字符。向下兼容

GB2312,向上支持 ISO 10646.1 国际标准。目前中文版的WIN95、WIN98、WINDOWS NT以及WINDOWS 2000、WINDOWS XP等都支持GBK编码方案。

1.3 UNICODE编码

    UNICODE采用两个字节,以“包容世界所有字符”为目标。UNICODE可以定义64K个字符。注意这里说的是UNICODE编码方式,并不代表UNICODE的传输方式。传输方式有采用变长字节方式如UTF-8编码方式。查看UNICODE的方式,在WINDOWS XP系统自带charmap(字符映射)程序,通过运行->charmap即可快捷查询字符UNICODE。

 2 编程练习

2.1 这里以WINDOWS XP系统,X86,VC++ 6.0为编程环境。

     WINDOWS为支持多字节字符串(即ASCII和汉字混杂)和UNICODE字符串。并且提供两种API来操作这两类字符串。但是可以使用_T宏来编写可移植程序。如下例,要指出的是,在使用多字节字符串时,定位汉字,要将高字节与低字节交换。因为一个汉字两个字节,0xD3C0,就会直接先存储D3再存储C0,所以需要交换字节。UNICODE则不必。

/*
#ifdef  _MBCS
#undef  _MBCS
#endif


#ifndef   _UNICODE
#define _UNICODE
#endif
*/
#include<iostream>
#include<tchar.h>
using namespace std ;


int _tmain()
{
    //setlocale ( LC_ALL, "" );
   setlocale(LC_ALL, "Chinese_People's Republic of China.936");  
    _TCHAR *szString=_T("永An empty street 空寂的街道An empty house 空寂的房间  \
   The rooms are getting smaller 无尽的孤寂压迫着我");
   wchar_t a , b;
    unsigned char   t1  ;
    b = _T('永')  ;
    int r  = _tcsclen(szString);  //计算字符串长度
   _tprintf(_T("%d\n"),r);
    _TCHAR   *p = _tcsinc(szString);
   while( *p !=NULL )
   {
         a   = *(wchar_t*)p ;
#ifndef  _UNICODE
        t1  = (a&0xff00)>>8 ;
       a = a<<8;
       a |= t1 ;
#endif
      if ( a == b)
      {
          _tprintf(_T("找到你啦"));
      }
       p = _tcsinc(p);   //移动字符串中指针
    }
return 0;
}

2.2 多字节和宽字节之间转换

在windows平台提供API为MultiByteToWideChar和WideCharToMultiByte两个。示例如下:

#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include <locale.h>
int main( int argc , char *argv[] )
{
       char  buf[64];
       wchar_t   wbuf[64];
       setlocale ( LC_ALL, "" );     //设置系统默认的OEM代码页
      //original equipment manufacturer (OEM).
       const wchar_t *p  =  L"生日快乐a";
       int len = ::wcslen(p);
       memset(buf,0,sizeof(buf));
       ::WideCharToMultiByte(CP_OEMCP,0,p,len,buf,sizeof(buf),NULL,NULL);
       printf("%s",buf);
       len = ::_mbstrlen(buf);
       //::MultiByteToWideChar(CP_ACP,0,buf,len,wbuf,sizeof(wbuf));
       // 注意这里的长度是字节的长度,-1表示整个字符串
       ::MultiByteToWideChar(CP_ACP,0,buf,-1,wbuf,sizeof(wbuf));
       wprintf(L"%s",wbuf);
       return 0;
}

原创粉丝点击