通透说Unicode.doc

上传人:ni****g 文档编号:547489760 上传时间:2023-07-20 格式:DOC 页数:4 大小:33.50KB
返回 下载 相关 举报
通透说Unicode.doc_第1页
第1页 / 共4页
通透说Unicode.doc_第2页
第2页 / 共4页
通透说Unicode.doc_第3页
第3页 / 共4页
通透说Unicode.doc_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《通透说Unicode.doc》由会员分享,可在线阅读,更多相关《通透说Unicode.doc(4页珍藏版)》请在金锄头文库上搜索。

1、Windows程序设计第二章学习心得|通透说Unicode这几天开始啃Charles Petzeld的Windows程序设计。啃到第二章时,为了搞清楚宽字符、UNICODE版本等这些问题,我特意分别编译了ASCII版本和UNICODE版本程序,并在虚拟机中装上Windows98,将其拖进去分别运行看效果!这里说下我学习第二章后的一些发现和心得!如何编译UNICODE版本程序我们平常编译出来的程序一般都是ASCII版本。由于平时没有要求,即使我们看了书,了解了点UNICODE版本的相关知识。但因为没有尝试过动手编译,我们对于UNICODE版本的认识还是很模糊的。不要光看不练,最好的学习方法应该付

2、诸于实践。让我们来尝试着编译一个UNICODE版本吧!如何下手呢?可能很多人会说:“书上说只要定义一个UNICODE标识符就OK了!”嗯,没错!说起来挺容易,但是可能很多人还不清楚这个“UNICODE”标识符怎么定义,在哪里定义?这个“UNICODE”标识符需要在源文件的最上方定义(当然,也在#include 等这些头包含预编译命令之上),即加上一句“#define UNICODE”。这边不必顾虑“#define UNICODE”右边是否有个常量。诸如“#define UNICODE 0”,“#define UNICODE 1”或者是“#define UNICODE 1234 ”这种形式都是可

3、以的,只要“UNICODE”这个标识符有被定义就成。搞不清楚的鹏友可以参考C语言参考手册或是C语言核心技术中关于“#ifndef”和“#ifdef”以及“#if”的相关用法。OK,“UNICODE”标识符定义完成。别以为这样就大功告成了。如果你尝试着去编译一下,你会失望的。编译器也许提示一堆烦人错误。别急,看一下错误报告!这时你将发现,哇,基本上都是关于类型转换的错误。不急,且往下看。修改代码,完成UNICODE版本编译前面杨老师在C语言也能干大事中一再提到,将字符串包在TEXT()宏里面。为啥?哈哈,现在终于知道啦!书中提到,UNICODE版本中,每个字符占2个字节。同时还提到,用“wcha

4、r_t”类型定义的字符数组在初始化时,需要在字符串前面加上“L”,如:cppwchar_t szRuPeng = L学在如鹏!;/cpp而宏TEXT,在编译UNICODE版本时将会在字符串前面加个“L”,如: cppTCHAR szRuPeng = TEXT(学在如鹏);/cpp定义了“UNICODE”标识符后,编译器会将上面语句改成: cppwchar_t szRuPeng = L学在如鹏!;/cpp这个就是关键所在了,后面出现的很多类型转换问题都得基于它去解决!之前鹏友们在学习杨老师的C语言也能干大事课程后,课下练习时可能会有这样的情况:把字符指针也放在TEXT()里面(这个字符指针包括指

5、向字符串的,指向字符数值的,或者直接就是字符串数组名)。如:cpp TCHAR szRuPeng = 学在如鹏; MessageBox(NULL, TEXT(szRuPeng), TEXT(如鹏), MB_OK);/cpp不知道这样做的鹏友多不多,至少我就这么做了。大家可能觉得这样做没什么问题,编译可以通过,程序执行似乎也完全正常。但是在编译UNCODE版本时,它却出事啦。错误报告可能是说发现未定义的标识符,怎么回事?原因在于TEXT宏会在字符串前面加个“L”,对于字符指针当然也不例外。于是就成了下面这样: MessageBoxW(NULL,LszRuPeng,L如鹏,MB_OK);Messa

6、geBoxW(NULL, LszRuPeng, L如鹏, MB_OK);显然跑出了一个未定义标识符“LszRuPeng”。所以,以后写代码时,除了字符串常量外,最好不要把字符指针放在TEXT()里面。推荐这样写: cpp TCHAR szRuPeng = TEXT(学在如鹏); MessageBox(NULL, szRuPeng, TEXT(如鹏), MB_OK);/cpp还有,格式化输出函数也不要放过。比如wsprintf,以前大家可能这么写:cppint iNum = 321;TCHAR szBuff256;ZeroMemory(szBuff, sizeof(szBuf);wsprintf

7、(szBuff, 计算机%d已经改为如鹏网啦!, iNum);/cpp咋一看没啥问题,同样在平时可以正常编译正常执行。可能有鹏友会说“sizeof(szBuf)应该换成sizeof(szBuf) / sizeof(TCHAR)”嗯,当然,这也是个问题。在UNICODE版本中sizeof(TCHAR) = 2,而ZeroMemory则是对memset函数改装的一个宏。它的功能是在指定的一段连续的内存空间中填充字符0。(在MSDN中查到memset的函数原型为:void *memset( void *dest, int c, size_t count);从第二个参数可以看出,它即能支持ASCII版

8、本,也能支持UNICODE版本,也就是说字符c既可以占1个字节,也可以占2个字节)在UNICODE版本中0占用2个字节。又因szBuff256也成了宽字符版,实际占用2 * 256 = 512个字节,故需要填充sizeof(szBuf) / sizeof(TCHAR) = 512 / 2 = 256个宽字符0(编译器会自动对该字符进行零扩充)。“OK,搞定问题!”别高兴地太早,这里还有个更可恨的问题没有被发现。再次编译一下UNICODE版本,又报错了。还是类型转换错误,可恨的类型转换。跟前面一样,还得把字符串放在TEXT()里面,于是就写成了下面这个德行: wsprintf(szBuff,TE

9、XT(计算机%d已经改为如鹏网啦!),iNum);wsprintf(szBuff, TEXT(计算机%d已经改为如鹏网啦!), iNum);是不是很别扭,可是人家就得要这样!因为wsprintf调用的是它的宽字符版即wsprintfW。于是上面的代码被编译器改成:cppint iNum = 321;wchar_t szBuff256;memset(szBuff, 0, sizeof(szBuf) / sizeof(wchar_t);wsprintfW(szBuff, L计算机%d已经改为如鹏网啦!, iNum);/cpp又解决了一个问题, 改啊改,改啊改,没完没了地改!继续往下看!如果有鹏友像

10、下面这样声明一个指向字符串的指针:cppTCHAR szRuPeng = TEXT(学在如鹏!); PSTR lpszRuPeng = szRuPeng;/*或者 LPSTR lpszRuPeng = szRuPeng; 或者 PCHAR lpszRuPeng = szRuPeng;又或者 char * lpszRuPeng = szRuPeng;*/cpp那么真是不好意思了,又要出问题啦。类型转换问题,万恶的类型转换问题啊!放下仇恨把,解铃还须系铃人。这时需要改成这样:cpp TCHAR szRuPeng = TEXT(学在如鹏!); PTSTR lpszRuPeng = szRuPeng;

11、/*或者 LPTSTR lpszRuPeng = szRuPeng;或者 PTCHAR lpszRuPeng = szRuPeng;又或者 TCHAR * lpszRuPeng = szRuPeng;*/cpp为什么?书上有,翻书可以找到答案。另外,杨老师的C语言也能干大事也经常提到的,跳转到它们的定义去看一下吧!我们可以想象到,诸如:cppchar szRuPeng = 学在如鹏!;char * lpszRuPeng = szRuPeng;/cpp这样的代码在编译UNICODE版本时虽然可以通过,但是显示的时候则会出一行乱码。所以我们写Windows程序时,在没有特定要求下(比如char s

12、zRuPeng = Study in RuPeng!;),最好使用Windows给我们提供的数据类型。如定义字符变量用TCHAR,定义字符指针用PTSTR,LPTSTR或TCHAR *,如此种种!同样需要注意的还有字符串处理函数的使用,也最好使用Windows提供给我们的,用lstrlen替代strlen等等,这些在Charles Petzold的书中已经讲得很详细了。同时,我们在学习杨老师的C语言也能干大事时,已经使用过很多这样的函数了!虽然目前我们都没有必要去编译UNICODE版本的程序。但是,在以后,也许工作上有要求,也许UNICODE有大行其道的那么一天,我们必须编写UNICODE版本

13、的程序。那么我们原有的编程习惯将会影响到我们个人发展。Unicode 是ASCII字符编码的一个扩展,用16位编码表示一个字符,这样就允许表示65536个字符,足够表示所有字符及世界上使用象形文字的语言。通常Unicode解释为宽字符。宽字符数据类型由wchar_t表示,占16位宽。wchar_t c = A; 变量c是一个双字节值0x0041,是Unicode表示的字母A。内存中存为41 00;wchar_t a = L”Hello!”; a字符串需要14个字节的存储空间,sizeof(a)将返回14。前面的L(代表long)即告诉编译器该字符串按宽字符保存。L通常用宏定义TEXT代替TCH

14、AR代替char(wchar_t)LPTCH、PTCH、PTSTR、LPTSRT代替char*(wchar_t*)LPCTSTR代替const char(const wchar_t*)TEXT(“string”)代替string(L“string”)lstrlen(); 代替strlen();lstrcpy(); 代替strcpy()lstrcpyn(); 代替strcpyn()lstrcat(); 代替strcat()lstrcmp();代替strcmp()lstrcmpi(); 代替strcmpi()wsprintf();代替sprintf ();(swprintf();)wvsprintf();代替vsprintf();(vswprintf();)

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 生活休闲 > 社会民生

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号