45fan.com - 路饭网

搜索: 您的位置主页 > 电脑频道 > 电脑教程 > 阅读资讯:Unicode的知识点介绍

Unicode的知识点介绍

2016-09-01 10:10:46 来源:www.45fan.com 【

Unicode的知识点介绍

Unicode的知识点介绍Unicode的知识点介绍Unicode的知识点介绍Unicode的知识点介绍Documents and Settings > weimaohua > Local Settings > Temp > FrontPageTempDir
About Unicode
Unicode的知识点介绍一. 简介
1.1 单字节与双字节字符集
1.2 Unicode:宽字节字符集
Unicode的知识点介绍1.3 编程时候的应用
1.3.1 可以选择编译
1.3.2 strcpy、_tcscpy、wcscpy
1.3.3 数据类型转换的宏
1.3.4 数据类型
二. 参考文献

关于Unicode及其相关


版本:1.0
作者:Soundboy
日期:2004-7-21
备注:本文介绍了关于字符集编码的一些知识

一. 简介

软件本地化等要处理不同的字符集。多年来,在一系列单字节字符后面放一个'/0'来处理。但是有些文字和书写规则(比如中文),字符太多了,单字节提供的256个字符根本不能满足需要。

1.1 单字节与双字节字符集

日文中的汉字,如果第一个字符在0x81与0x9F之间,或者在()xE0与0xFC之间,那么就必须观察下一个字节,才能完整确定这个字符。MS VC++中有许多函数,例如_mbslen(),可以用来操作多字节字符集(DBCS)

1.2 Unicode:宽字节字符集

有一个专门的机构来维护Unicode标准。每个Unicode字符是16位的,一共有65000个字符。目前许多文件都有自己的字符在Unicode中的位置,称为代码点。中文拼音的代码点是0250~02AF。

1.3 编程时候的应用

只需要定义两个宏(UNICODE和_UNICODE)就可以了。标准的C头文件string.h里面,多了一个wchar_t的数据类型。

typedef unsigned short wchar_t;

原来的对字符串操作的基本C函数不能对Unicode操作,只能对ANSI C操作,对于Unicode操作时候只要把str改为wcs就可以了。例如

strcmp() --> wcscmp()

1.3.1 可以选择编译

可以同时建立为ANSI 和 Unicode的进行编译的文件,必须包含"TChar.h"文件,而不是"STring.h"。TChar.h文件中包含一组宏,如果定义了_UNICODE,那么就会用wcs组函数,否则将引用str组函数。

1.3.2 strcpy、_tcscpy、wcscpy

在TChar.h中有一个_tcscpy函数,如果编译的时候没有定义_UNICODE,这个函数就作为strcpy,如果定了就变成了Unicode函数wcscpy()。这样,程序就能顺利地进行ANSI或者Unicode编译了。

1.3.3 数据类型转换的宏

对于THCAR这种类型,如果定义了_UNICODE,那么就有

typedef wchar_t TCHAR;

如果没有定义,那么

typedef char TCHAR;

而且可以TCHAR *szError = "Error";

但是这样定义了Unicode,那么这样将会有一个错误,必须使用 szError = L"Error";

加上L以后编译器在数据段地前面加上4个零字节。但是这样又不是何ANSI了。因此用_TEXT()宏可以完成这个事情。例如:

TCHAR * szError = _TEXT("Error");

这样对于Unicode和ANSI都可以正确地编译了。

1.3.4 数据类型

WCHAR Unicode字符

PWCHAR Unicode字符串指针

PCWCHAR Unicode字符串常量指针

PTSTR和PCTSTR既可以指向Unicode,也可以指向ANSI字符串,取决与是否定义了_UNicode宏。

二. 参考文献

《Windows核心编程》Jeffrey Richter

以下是李智勇的文章,我在这里收藏

说说字符集

03-8-8 18:02 by leezy_2000

由于作者是美国人的缘故,我发现Windows下的几本名著(如《Windows程序设计》,Jeffrey Richter的《Windows 核心编程》)对字符集的讲解都不甚透彻。现在这里对一些易让人迷惑的问题进行澄清,并指明一些编程时容易出错的问题(我自己就犯过)。

先解释几个概念:

字符集:根据编码特性而分,字符集可分为三类。

l 窄字符集(SBCS 每个代码由一个字节进行表示,比如ANSI

l 多字节字符集(MBCS 字符集中的代码或者是单字节,或者是多字节,比如DBCSGB2312等。

l 宽字节字符集 字符集中每个字符由两个字节表示。比如UNICODE

代码页:UNICODEDBCS中由于包含的代码十分多,为了使用方便就需要对这些代码进行组织。组织的方法就是把不同国家的代码分别放入不同的代码页。

字符集与代码页的关系:由上可知,对于UNICODEDBCS,代码页是从属于字符集的。但对于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;

}

 最后总结一下,这篇文章的主题就是在做字符集间的转换时,一定要动态确定代码页。
 

本文地址:http://www.45fan.com/dnjc/70677.html
Tags: 关于 unicode Documents
编辑:路饭网
关于我们 | 联系我们 | 友情链接 | 网站地图 | Sitemap | App | 返回顶部