新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → Win32学习笔记- Unicode 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 3957 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: Win32学习笔记- Unicode 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 Win32学习笔记- Unicode

    佛曰:众生皆平等。但是人却可以利用较高等的智慧站在了众多生物的至高点。吃早饭的时候我看着被做成菜的那条鱼,想到它也是生命。所以说到底,还是有些等级之分。学习WIN32过程中让我知道了Unicode的存在。Unicode最终会取代ASCII码成为标准。但是之前还有很长一段路要走。虽然Unicode的优势很明显,但是因为历史遗留问题,ASCII会存在很长一段时间。

    学习C语言的时候您应该接触过ASCII码。学习本章的内容需要ASCII知识。

    学习Unicode有必要了解字符集的历史。从最早的象形字开始,我们使用字符文字已经有近6000年了。19世纪的几个发明家发明了电报,当时在电报中使用的代码是Morse代码。字母表中的每个字符对应于一系列短和长的脉冲。

    计算机是处理的数据其实是一系列1和0。每一段数字都代表一种字符。这就是ASCII码。7位数的ASCII码对于美国的字符集支持得很好。不幸的是地球上有一百多个国家和地区,2000多个民族。对于美国以外的用户来讲在计算机中显示自己国家的文字困难重重。

    尤其是中国,日本,朝鲜更是如此。以中国为例,有数也数不清的汉字。办法总是有的。人们引入了"代码页"和"双字节字符集"的概念。这种编码方式非常庞大和复杂,不利于维护。这个时候Unicode应运而生了。

    Unicode的解决方案非常简单。既然不能用7位或者8位数值表示,那么我们应该试一下更宽的值。例如16位,这样就允许表示65536个字符。Unicode和ASCII是兼容的。也就是说,前128个字符的数值是相同的。

    Unicode的最大好处是只有一个字符集。当然Unicode也有缺点,Unicode占用的内存是ASCII码的两倍。而且人们还不太习惯Unicode。

    对于程序员来讲,8位的ASCII码和16位的Unicode是我们必须面对的问题。为了解决宽字符(16位)问题,Windows在头文件中定义了"新"数据类型。

    typedef unsigned short wchar_t;

    可以看出wchar_t其实是16位的无符号短整型数。Windows用这种方法存贮16位字符。

    wchar_t *p = L"Hello!";

    在"Hello!"前有一个大写字母L(代表lo


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/11/21 14:56:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    ng)。这将告诉编译器该字符串按宽字符保存。即每个字符占用2个字符。存贮该字符串需要14个字节。字符串末尾还有一个/0也需要2个字节。

    我们都知道如何获得字符串的长度。

    int iLength;
    char *pc = "Hello!";
    iLength = strlen(pc);

    函数strlen()返回字符串的长度,长度将不包括末尾的/0。变量iLength将等于6,也就是字符串中的字符数。

    接下来我们试着用strlen()检查宽字符的字符串。

    wchar_t *pw = L"Hello!";
    iLength = strlen(pw);

    strlen()的参数应该是char类型的指针,但是现在却接受了一个unsigned short类型的指针。编译后您会发现iLength等于1。

    why?字符串"Hello!"中的6个字符宽字符代码如下:

    0x0048 0x0065 0x006c 0x006c 0x006f 0x0021

    Intel处理器在内存中将其存为:

    48 00 65 00 6c 00 6c 00 6f 00 21 00

    strlen()的工作过程是遇到0就结束。因为0表示一个字符串的结束。当读完"48"后strlen()遇到的是0,所以strlen()返回1。

    由上例可以看出C语言的函数无法正确处理宽字符。在参数中有字符串的函数全部需要重写。strlen()的宽字符版本是wcslen(),并且在STRING.H中和WCHAR.H中均有声明.

    现在我们知道,要得到宽字符串的长度,可以调用

    iLength = wcslen(pw);

    该函数返回将返回字符串中的字符数6。请记住,改成宽字节后字符串的字符长度不变,只是字节长度改变了。千万不要混淆。

    因为Unicode占用两倍的存储空间,所以宽字节运行库中的函数比常规的函数大。所以最好是建立两个版本的程序,一个处理ASCII字符串,另一个处理Unicode字符串。但是这样以来又引来了另一个小问题。因为每一个实现特定功能的函数都有两个版本,所以名字不好记。不管是ASCII版本还是Unicode版本,都用相同的名字该多好啊?幸好这个问题已经得到了解决。

    解决办法是使用Visual C++包含的TCHAR.H头文件。该头文件不是标准C的一部分。为了与标准C的头文件分别开来,该头文件内定义的每个函数和宏定义的前面都有一条下划线。


    TCHAR.H为需要字符串的标准运行库函数提供了一系列的替代名称。有时这些名称被称为"通用"函数名,因为它们既可以指向函数的Unicode版本,也可以指向ASCII版本。
    以_tcslen()为例如果定义了_UNICODE的标识符,并且程序中包含了TCHAR.H,那么_tcslen()就定义为wcslen():

    #define _tcslen wcslen

    如果没有定义_UNICODE,则_tcslen()被定义为strlen()。

    #define _tcslen strlen

    TCHAR.H还用一个新的数据类型TCHAR来解决两种字符数据类型的问题。如果定义了_UNICODE标识符,那么TCHAR就是wchar_t:

    typedef wchar_t TCHAR;

    否则TCHAR就是char:

    typedef char TCHAR;

    还记得第一章里出现过的TEXT()吗?那是为了兼容UNICODE字符集所做的改动。下面就来看看TEXT()在头文件中是怎么定义的。

    #define __T(x)    L##x

    后面的L##x您可能看不懂。很少有书提到它。但那确实是标准C预处理的一部分。这一对"##"称为粘贴号(token paste)。看来我们对标准C的了解还不够。是时候买本"The C Programming Language"了。它将字母L添加到宏参数上。

    __T("Hello!") 等于 L##"Hello!" 等于 L"Hello!"。

    此外还有两个宏与__T定义相同:

    #define _T(x) __T(x)
    #define _TEXT(x) __T(x)

    WINNT.H头文件中还定义了一个宏,该宏也跟__T一样,将L添加到字符串前。

    #ifdef UNICODE
    #define __TE
    XT(quote) L##quote
    #else
    #define __TEXT(quote) quote
    #endif

    #define TEXT(quote) __TEXT(quote)

    在本书中使用的就是TEXT(quote)。现在您知道了为什么会把字符串用TEXT()括起来了吧。what?还不明白?您可以先恶补标准C,然后再多读几遍。再不会那就是天份问题了。不过,连像我这样的村民都能看懂,您没理由不会啊!

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/11/21 14:56:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客3
    发贴心情 
    问题整理:
    1、我现在需要用unicode编译,但是不知如何设置? 我只能在设置选项里选择:release或debug

    Project   Setting->C/C++(General)->Preprocessor   definitions里加上UNICODE进行设置。
    2、
      >>我的问题是如何定义一个TCHAR型变量(或者别的变量也行)读入整个的中文,使之可以与??>>short型变量相互转换。       
      你可以使用sizeof(TCHAR)来跳过一个中文。   
    3、
      >>我已经完成了两位说所的一切工作,但是还是不行   
      >>我在一个新建工程(没有进行任何的改动)的头文件中   stdafx.h   (在包含所有头文件之前)>>加入#define   _UNICODE则编译不能通过   
      >>Generating   Code...   
      >>nking...   
      >>msvcrtd.lib(crtexew.obj)   :   error   LNK2001:   unresolved   external   symbol   >>_WinMain@16   
      >>Debug/unicode1.exe   :   fatal   error   LNK1120:   1   unresolved   externals   
      >>Error   executing   link.exe.   
      >>unicode1.exe   -   2   error(s),   0   warning(s)   
      >>如果在包含头文件后加入则无效   
        
      请你在Project   setting>>Link>>Category:Output>>Entry-point   symbol里填入   
      wWinMainCRTStartup   

    我把"中文"赋值给一个CString   s,按道理s中的值应该是Unicode编码的,也就是4E   2D   65   87,可是跟踪时却发现s为D6   D0   CE   C4,还是GB2312编码.根本就没有用Unicode.   
        
      #ifndef   _UNICODE   
      #define   _UNICODE   
      #endif   
        
      CString   s;   
      s=_T("中文");   
        
      为何s没有用Unicode表示"中文"??

    答:
    L("中文") 或在afx.h最前面定义_UNICODE

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/11/21 15:02:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/23 4:15:25

    本主题贴数3,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    77.148ms