ASCII、MBCS、UNICODE

来源:互联网 发布:中芝生物灯价格淘宝 编辑:程序博客网 时间:2024/06/06 08:43

1、ASCII字符集

      ASCII字符集使用char类型存储字符,一个字节表示一个字符,由95个可打印字符(字母、数字、标点符号)和33个控制字符(换行、回车、制表、退格、响铃等)组成只能表示英文或其它字符故只能在英文操作系统上使用。由于他是针对英语设计的,当处理带有音调标号(形如汉语的拼音)的欧洲文字时就会出现问题,因此,又创建出了包括255个字符的ASCII扩展字符集。

2、多字节字符集(MBCS)

      后来其它国家相继发明了适合自己语种的字符集,使之能表示自己国家的语言,能在自己语种的操作系统上使用。如中国的GB2312和GBK(GB2312的扩展),这两个字符集都是使用1-2个字节来表示一个字符,称为多字节字符集。多字节字符集使用char类型存储字符,一个英文字母占一个字节,一个汉字一般占两个字节。对应处理函数如printf()、atoi()等,对应字符串处理函数以str开头,如strlen(),strcpy()等。VS中使用MBCS字符集的话CString中一个汉字的长度为2string中一个汉字长度为2。Windows中可以用PSTR、LPSTR、LPCSTR等来表示指向这种类型的字符串指针。

3、unicode字符集

      unicode字符集是能表示全球所有国家语言的字符集,故又称万国码。Unicode使用 2或4个字节来表示一个字符,绝大部分2个字节就够了。现在机器上的unicode编码一般指的是UTF-16:使用两个字节来表示一个字符。unicode字符集使用wchar_t类型存储字符一个英文字母占两个字节,一个汉字一般占两个字节。对应处理函数如wprintf()、_wtoi()等,对应字符串处理函数以wcs开头,如wcslen(),wcscpy()等。VS中使用unicode字符集的话CString中一个汉字的长度为1string中一个汉字长度为2。Windows中可以用PWSTR、LPWSTR、LPCWSTR等来表示指向这种类型的字符串指针。C/C++中字符串常量为const char*类型,可以在其前面加L转化为const wchar_t*类型,如const wchar_t* p = L"abc";。C++ iostream类库也提供了wchar_t宽字符类型的相关操作,如std::wcin,std::wcout等。

4、UTF-8

     对可以用ASCⅡ表示的字符使用Unicode并不高效,因为Unicode比ASCⅡ占用大一倍的空间,而对ASCⅡ来说其高字节的0对他毫无用处。为了解决这个问题,就出现了UTF-8,它是一种针对Unicode的可变长度字符编码,使用1个到6个字节来表示一个字符。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部份修改,即可继续使用

5、使用UTF-8还是UTF-16

用UTF-16表示"汉":

使用UTF-16表示的话就是01101100   01001001(共16 bit,两个字节),程序解析的时候知道使用的UTF-16,就把两个字节当成一个单元来解析,这个很简单。

用UTF-8表示"汉":

用UTF-8就有复杂点,因为此时程序是把一个字节一个字节的来读取,然后再根据字节中开头的bit标志来识别是该把1个还是两个或三个字节做为一个单元来处理.

0xxxxxxx,如果是这样的格式就表示把一个字节做为一个单元.就跟ASCII完全一样.

110xxxxx 10xxxxxx.如果是这样的格式则把两个字节当一个单元

1110xxxx 10xxxxxx 10xxxxxx 如果是这种格式则是三个字节当一个单元.

我们知道UTF-16不需要用啥字符来做标志,所以两字节也就是2的16次能表示65536个字符。

而UTF-8由于里面有额外的标志信息,所有一个字节只能表示2的7次方128个字符,两个字节只能表示2的11次方2048个字符,而三个字节能表示2的16次方,65536个字符。

由于"汉"的编码27721大于2048,所以两个字节还不够,只能用三个字节来表示。

于是UTF-8和UTF-16的优劣很容易就看出来了,如果全部英文或英文占绝大部分,用UTF-8就比UTF-16节省了很多空间;而如果全部是中文这样类似的字符或者中文占绝大多数,UTF-16就占优势了,可以节省很多空间。

6、ANSI标准

      不同ASCII衍生字符集的出现,让文档交流变得非常困难,因此各种组织都陆续进行了标准化流程。例如美国ANSI组织制定了ANSI标准字符编码。注意,我们现在通常说到的ANSI编码,通常指的是平台的默认编码,例如中文操作系统是GBK,GBK属于多字节字符集类型,其它的还有IOS标准、国家标准。

7、TCHAR、_TEXT()、_T()

     VS中的TCHAR在使用ANSI编码时即为char,使用UNICODE则为wchar_t,同样_T()与_TEXT()可以根据你的环境设置,选择对应的字符处理方式(Unicode还是MBCS)。对应处理函数如_tprintf()、_ttoi()等,对应字符串处理函数以_tcs开头,如_tcslen(),_tcscpy()等。Windows中可以用PTSTR、LPTSTR、LPCTSTR等来表示指向这种类型的字符串指针。


8、宽字符

      用多个字节来存储的字符称之为宽字符,而Unicode只是宽字符编码的一种实现,宽字符并不一定是Unicode。

9、术语解释

     字符集:字面上的理解就是字符的集合,例如ASCII字符集,定义了128个字符;GB2312定义了7445个字符。

     字符码:指的就是字符集中每个字符的数字编号。例如ASCII字符集用0-127这连续的128个数字分别表示128个字符;

     字符编码:将字符集中的字符码转换为字节流的一种具体实现方案。例如ASCII字符编码规定使用单字节中低位的7个比特去编码所有的字符。例如‘A’的编号是65,用单字节表示就是0x41,因此写入存储设备的时候就是b’01000001’。

     字符解码:将字节流解析成字符集中的字符码。

10、char与wchar_t之间相互转换

      WideCharToMultiByte()函数可以将unicode字符串转换为ANSI字符串或将unicode字符串转换为UTF-8字符串。

      函数原型:
      int WideCharToMultiByte(
      UINT CodePage, //执行转换的代码页.使用CP_ACP代码页实现ANSI与Unicode之间的转换,使用CP_UTF8代码页实现UTF-8与Unicode之间的转换
      DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符
      LPCWSTR lpWideCharStr, //要转换的宽字节字符串的缓冲区
      int cchWideChar, //参数lpWideCharStr指向的缓冲区的字符个数
      LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区
      int cchMultiByte, //参数lpMultiByteStr指向的缓冲区最大值
      LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符
      LPBOOL pfUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE
      );

    eg: 

char* wchar2char(wchar_t* wchWideStr){char* chMultiStr = NULL;try{int iLen = wcslen(wchWideStr)*2;//wchar_t中汉字长度为1chMultiStr = new char[iLen+1];memset(chMultiStr, 0, iLen+1);int nWideStrLen = wcslen(wchWideStr);int nMultiStrByte = iLen+1;WideCharToMultiByte(CP_ACP, 0, wchWideStr, nWideStrLen, chMultiStr, nMultiStrByte, 0, 0);}catch(...){if(chMultiStr != NULL){delete[] chMultiStr;chMultiStr = NULL;}throw;}return chMultiStr;}

    MultiByteToWideChar()函数可以将ANSI字符转化为unicode字符串或将UTF-8字符串转换为unicode字符串。

      函数原型:
      int MultiByteToWideChar(
      UINT CodePage,
      DWORD dwFlags,
      LPCSTR lpMultiByteStr,
      int cchMultiByte,
      LPWSTR lpWideCharStr,
      int cchWideChar
      );

      eg:

wchar_t* char2wchar(const char *chMultiStr){wchar_t *wchWideStr = NULL;try{int iLen = strlen(chMultiStr);//char中汉字长度为2wchWideStr = new wchar_t[iLen+1];memset(wchWideStr, 0, (iLen+1)*2);int nMultiStrByte = strlen(chMultiStr)+1;int nWideStrLen = iLen+1;MultiByteToWideChar(CP_ACP, 0, chMultiStr, nMultiStrByte, wchWideStr, nWideStrLen);}catch(...){if(wchWideStr != NULL){delete[] wchWideStr;wchWideStr = NULL;}throw;}return wchWideStr;}

      vc++中还有CW2A和CA2W宏,分别用来将unicode字符转换为ANSI字符,将ANSI字符转换为unicode字符。


      参考及部分转载出处:http://hi.baidu.com/original/item/0521d9fea484185cc8f33753

               http://baike.baidu.com/link?url=uwSvEvHwofcwuX-f7TwD5vJKKm2DEtRWSWbkGHGMV85mJjqc-JxocG9bxBiramh7Ibjk0WYDvDSLdv6f_J2aR_

               http://www.cnblogs.com/KevinYang/archive/2010/06/18/1760597.html

               http://www.cnblogs.com/kingcat/archive/2012/10/16/2726334.html

0 0
原创粉丝点击