说说字符集

原创 2007年09月22日 16:34:00
 

HTML Tags and JavaScript tutorial



说说字符集




由于作者是美国人的缘故,我发现Windows下的几本名著(如《Windows程序设计》,Jeffrey Richter的《Windows 核心编程》)对字符集的讲解都不甚透彻。现在这里对一些易让人迷惑的问题进行澄清,并指明一些编程时容易出错的问题(我自己就犯过)。
 先解释几个概念:
 字符集:根据编码特性而分,字符集可分为三类。
l         窄字符集(SBCS) 每个代码由一个字节进行表示,比如ANSI。
l         多字节字符集(MBCS) 字符集中的代码或者是单字节,或者是多字节,比如DBCS,GB2312等。
l         宽字节字符集   字符集中每个字符由两个字节表示。比如UNICODE
      代码页:在UNICODE和DBCS中由于包含的代码十分多,为了使用方便就需要对这些代码进行组织。组织的方法就是把不同国家的代码分别放入不同的代码页。
      字符集与代码页的关系:由上可知,对于UNICODE和DBCS,代码页是从属于字符集的。但对于SBCS类的字符集(比如ANSI)和DBCS之外的MBCS字符集(比如GB2312等)他们则只对应于一个代码页。
       下面看一段潜在有问题的程序:
void ConverAndOutputString(HDC hdc,LPWSTR wstr, int length,int x,int y)
{
      int nret;
      int sizebuffer= 2*length;
      char* lpBuffer=new char[sizebuffer];
      nret=WideCharToMultiByte(CP_ACP,0,wstr , length,lpBuffer, sizebuffer ,NULL,NULL);
      TextOut(hdc,x,y, lpBuffer,nret);
      delete[]lpBuffer;
}
      这段程序很简单,只是把一个宽字符串转为DBCS串而后按指定的坐标进行输出。Jeffrey Richter在他的《Windows核心编程》中的第26页也用几乎的相同的方法进行字符串转换。但这段程序其实是有问题的。问题出在转换字符串时不应该硬编码指定代码页,而应该根据当前字体进行动态获取。否则在某些情况下将无法把wstr中的UNICODE字符转换到正确的代码。如果你用上述代码进行中文输出,你将很有幸看到很多问号被自动添加到你的字符串中。
      解决的办法也很简单,但首先你要熟悉如下两个个API函数:
      int GetTextCharset(HDC hdc);//这个API用来得到当前字体的字符集。
       BOOL TranslateCharsetInfo(
          DWORD* pSrc,        // information
          LPCHARSETINFO lpCs,  // character set information
          DWORD dwFlags        // translation option
        );
      这个函数可以把字符集、代码页和FONTSIGNATURE互相转换。转换后的信息放在lpCS中。dwFlags指明需要进行那种转换,是把字符集转换到代码页还是其他。特别需要注意的是,pSRC参数,这个参数在你进行字符集到代码页转换的时候,需要的是一个具有指针类型的值而非指向某个值的指针。因此对上述字符串输出函数你只要加上如下两行,就可以保证字符串在转换期间不会遇到找不到字符代码的情况。
void ConverAndOutputString(HDC hdc,LPWSTR wstr, int length,int x,int y)
{
      int nret;
      int sizebuffer= 2*length;
      char* lpBuffer=new char[sizebuffer];
      int charset=GetTextCharset(hDC);
      CHARSETINFO csinfo={0};
      TranslateCharsetInfo((DWORD*)charset,&csinfo,TCI_SRCCHARSET);
      nret=WideCharToMultiByte(csinfo. .ciACP,0,wstr , length,lpBuffer, sizebuffer ,NULL,NULL);
      TextOut(hdc,x,y, lpBuffer,nret);
      delete[]lpBuffer;
}
      最后总结一下,这篇文章的主题就是在做字符集间的转换时,一定要动态确定代码页。所涉及函数和结构的进一步细节请参考MSDN。 


说说字符集和编码

很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物。他们看到8个开关状态是好的,于是他们把这称为"字节"。 再后来,他们又做了一些可以处理这些字节的机器,机器...

熟知Oracle字符集

  • 2013年09月01日 21:58
  • 162KB
  • 下载

字符集ORACLE

  • 2013年10月17日 16:27
  • 8KB
  • 下载

Oracle 11gR2修改服务器端字符集

查看字符集编码的命令为: SQL>  select userenv('language') from dual; USERENV('LANGUAGE') -----------------------...

linux 下修改字符集的问题

  • 2013年07月09日 20:01
  • 548B
  • 下载

检查文档的字符集

  • 2016年01月08日 16:16
  • 1KB
  • 下载

关于MYSQL在UTF-8字符集下乱码的解决办法

from http://www.itxx.com.cn/data/mysql/data_1969.html 怎样解决MYSQL数据库在UTF-8字符集下乱码?经常会有人遇到这样的问题,MYSQL数据...
  • leehwi
  • leehwi
  • 2014年03月30日 22:45
  • 1212

字符集和编码高度概括 (英文)

  • 2016年01月07日 23:10
  • 175KB
  • 下载

DB2字符集和代码页设置常识

DB2中采用代码方式指定字符集,有些困惑,所以特地整理了如下两张表,由于偶们是中国人,所以就不列多余的字符集啦,下面仅仅列出PRC的字符集,这样建库指定字符集和代码页就不会迷糊了,而且字符集往往困扰了...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:说说字符集
举报原因:
原因补充:

(最多只允许输入30个字)