| 首页 | 新闻 | 网页 | 设计 | 色彩 | 原创 | 视觉 | 素材 | 动漫 | 酷站 | 策划 | 文案 | 访谈 | 运营 | 编程 | 数据库 | 服务器 | 下载 | 图库 | 
您的位置: 幽幽天空 > 网页 > 编程开发 > Visual C++教程 > 文章正文 用户登录
说说几类有发展钱
说说几类有发展钱
判断字符or汉字的
我也来说说鼠绘
从外部文本载入特
函数版的 String.
说说异或运算^和他
用IPTables实现字
SQL Server中全角
影响ORACLE汉字显

说说字符集           

说说字符集

作者:佚名 来源:CSDN 作者: leezy_2000 更新:2006-8-25 21:05:35 错误报告 我要投稿

  由于作者是美国人的缘故,我发现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。 
文章录入:skyuu    责任编辑:skyuu 
  • 上一篇文章:

  • 下一篇文章:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    发表评论:
    姓名:  评 分: 1分 2分 3分 4分 5分
     
  • 严禁发表危害国家安全、政治、黄色淫秽等内容的评论。
  • 用户需对自己在使用幽幽天空服务过程中的行为承担法律责任。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表机友个人观点,与本网站立场无关。