说说字符集<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
03-8-8 18:02 by leezy_2000
由于作者是美国人的缘故,我发现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。
分享到:
相关推荐
- **字符集兼容性**: 不同的操作系统可能使用不同的默认字符集,因此在进行转换时要确保字符集的一致性。 - **乱码问题**: 如果在编码或解码时使用的字符集不一致,可能会导致乱码问题。 - **Unicode编码**: Java中...
OCR,即光学字符识别技术,可以将图片、纸质文档上的文字转换成可编辑、可搜索的电子文档。这种技术的应用,极大地便利了人们的生活,尤其是对于那些包含文字的图片或者古老书籍的数字化工作。想象一下,在寻找一些...
你需要解析网页源代码,找到包含说说内容的HTML元素,并通过易语言的字符串处理函数来提取相关信息。 在"说说提取.e"这个源文件中,我们可以预见到程序会包含以下几个主要部分: 1. **登录模块**:利用易语言的...
ASC16是一种支持ASCII字符集的16x16像素点阵字体,主要应用于早期的计算机系统或者资源有限的设备上。ASCII字符集包含了英文大小写字母、数字、标点符号以及一些特殊字符,覆盖了基本的文本输入需求。由于其小尺寸和...
ANSI编码是一种基于区域设置的字符编码方式,而在Windows操作系统中,UNICODE是使用两个字节表示每个字符的编码标准,能支持更广泛的字符集。在处理字符串时,如果从ANSI编码转换为UNICODE,需要进行字符编码的转换...
首先,`UNICODE`,全称为Unicode Transformation Format,是一种全球通用的字符集,旨在统一世界上所有语言的字符编码,避免乱码问题。它使用16位的编码空间,理论上可以表示1048576个不同的字符,覆盖了世界上几乎...
GBK编码是基于ASCII的,因此它兼容ASCII字符集,但不支持Unicode,这可能会导致在处理多语言文本时出现问题。 其次,Unicode 是一个国际标准,旨在为世界上所有语言提供一个统一的字符编码方式。Unicode通过分配...
这个类库可能包含了对AES、DES、RSA等常见加密算法的支持,允许开发者对字符串、文件或流进行加密和解密。这些方法通常提供了一种安全的方式来保护敏感信息,确保数据在传输或存储过程中的安全性。 再来说说XML操作...
接着,我们来到Unicode,这是一个统一的字符集,包含了世界上几乎所有的文字,包括汉字。Unicode采用固定长度的编码,常见的有UTF-8、UTF-16和UTF-32。其中,UTF-8是最广泛使用的,它使用1至4个字节来表示一个字符,...
`来查看当前数据库的字符集。 #### 11. 如何查看当前数据库版本 使用命令`SELECT VERSION();`来查看当前MySQL数据库版本。 #### 12. 如何查看当前登录的用户。 使用命令`SELECT USER();`来查看当前登录的用户名...
支持Unicode、多字符集,支持Well-formed和Validated两种类型的XML文档,支持NewsML等多种标准XML文档的所见即所得的编辑,同时提供了强有力的样式表设计。 Altova希望其最新发布的XMLSpy会让XML代码的处理更容易...
- 可以,因为Java的`char`类型占用16位,可以表示Unicode字符集,包括中文汉字。 9. 用最有效率的方法算出2乘以8等于几? - 直接写`2 * 8`是最简单的,Java会快速计算这个基本操作。 10. 冒泡排序实现: - 冒泡...
Java 面试问题集 Java 是一种广泛使用的编程语言,具有强大、灵活、跨平台等特点。Java 面试是一种常见的编程面试形式,旨在考察候选人的 Java 编程知识和技能。本文档提供了 20 个 Java 面试问题,涵盖了 Java ...
十六进制使用了0-9和A-F的字符集,其中A-F代表十进制中的10-15。十六进制在表示大型二进制数时非常方便,因其可以将很长的二进制数简化为较短的形式。 **二进制转十六进制**:采用“取四合一法”,每四位二进制数...
总结来说,这款升级版的字模提取软件集字模提取、内码查看和个性化造字于一身,同时还具备批量处理能力,对于设计师、程序员、排版师等专业人士以及对文字艺术有兴趣的普通用户来说,都是一个极具价值的工具。...
3. 字符串类型(String)。 4. 日期时间类型(Datetime)。 5. 布尔类型(Boolean)。 存储引擎 Mysql 的存储引擎包括: 1. InnoDB。 2. MyISAM。 3. MEMORY。 InnoDB 和 MyISAM 的区别 InnoDB 和 MyISAM 的...
ASCII仅支持英文字符,而Unicode则覆盖了世界上大多数语言的字符,其中UTF-8是目前最广泛使用的编码方式,它能表示Unicode字符集。在Python中,我们可以通过`encode()`函数将字符串转换为字节流,例如`str.encode('...
易语言源码是由易语言编写的应用程序的原始指令集,包含了程序的所有逻辑和功能。通过阅读和分析源码,开发者可以理解程序的工作原理,进行修改、优化或二次开发。这个压缩包中的源码应该是一个实现了将十六进制数字...