zoukankan      html  css  js  c++  java
  • 编写符合ANSI和Unicode的应用程序

    世界真的很奇妙,分久必合,合久必分。

    计算机发展到今天,多国之间的交流日益广泛,软件本地化是重大趋势。如果减少本地化工作就是一件值得考虑的事情。

    软件本地化要解决的真正问题就是如何来处理不同的字符集。要知道,单字节字符是一个8位的数据来表示的。 因此,它最多能表示256个字符。 全世界那么多个国家,256个怎么够。 因此人们提出了双字节(DBCS)来解决这个问题。

    单字节与双字节字符集 ----->多字符集

    当表示英文或某些符号的时候,就采用一个字节来表示,而当表示日文,中文等字符的时候,就采用两个位来表示。 可想而知,我们不可以再像操作单字节字符那样通过 pChar++;来遍历每一个字符。

    为此,MS提供了CharNext,CharPre作为遍历工具。 不过这些函数让人头疼。

    Unicode应运而生。它采用了两个字节来表示一个字符,不管是汉字还是英文。 统一一样。 两个字节即为16位,表示的数有65536个。 而世界各国的符号加起来才用了35000个左右,困此,足够了。

    为什么我们要使用Unicode

     当开发应用程序时,当然应该考虑利用Unicode的优点。即使你不打算让你的程序本地化,开发时也应该将Unicde放在心上,肯定可以简化你将来的代码转换工作。此外,Unicde还有以下功能。

       1、可以很容易地在不同语言之彰进行数据交换。

       2、使你能够分配支持所有语言的单个二进制.exe文件或dll文件。

       3、提高应用程序的运行效率。

    WINDOWS 2000上的Unicode

    WINDOWS 2000是采用Unicode从头开发的。 所有与字符串相关的操作都会用到Unicode。当然,WINDOWS 2000的API都接受多字符集和Unicode字符集的参数。但是,只有Unicode的函数是实现了的。而多字符集的函数则是先将Unicode字符集转换成Unicode,然后再交给Unicode的函数处理。可知,采用Unicode调用API,速度会快不少。 同样,返回字符串的API函数也做同样的转换工作。

    系统中会存在两套API 拿CreateFile为例。则有如下定义

    #ifdef UNICODE

    #define CreateFileW CreateFile

    #else

    #define CreateFileA  CreateFile

    #endif

    当我们调用 CreateFile的时候,系统便会根据你是否要UNICODE而选择正常的函数。

    而当你调用CreateFileA时,则有

    调用CreateFileA---> 将多字符集参数转换为Unicode ---> 调用 CreateFileW

    白白地多了转换工作。因此,采用Unicode编程,可以提高效率。  

    还有一些关于WINDOWS 98的就不介绍了。。需要知道的就是,WIN 98不支持Unicode,所以,强制调用W结尾的函数再用GetLastError()取得错误信息,你会发现提示你此函数没有实现。

    WINDOWS CE则是完完全全的Unicode操作系统,不支持ANSI.....

    如何使用UNICODE

    数据类型

        为了和ANSI有所区别,UNICODE版本的数据类型显然会不一样.

    char   wchar_t

    而wchar_t的定义为 typedef unsigned shot wchar_t

    可见,它是16位的。

    而对于常用的字符串操作函数,对比如下

    strcpy  wcscpy

    strcat wcscat

    。。。

    str 被换成了wcs 即 wide  character string的缩写

     

    上面是C运行期库的定义,由于MS提供的C运行期库与ANSI标准是一样的。所以上面的宽字符操作依然对WIN 98有效。

     

    对于UNICODE的使用,我们则不能直接使用上面的函数,因为这样的话,ANSI/Unicode源码转换时你会哭掉。

    于是,我们应该使用像

     

    #ifdef UNICODE

    #define _strcpy  wcscpy

    #else

    #define _strcpy  strcpy

    #endif

     

    这样的宏来使用每一个函数,而 TChar.h 头文件已经帮我们做到了。只需包含它,并使用正确的经过宏控制的函数名和类型。就可以很轻松地实现。。。

    对于字符串的赋值。

     

    char* p = "ook";

    wchar_t *p = "ook";//错误

     

    而应该是

    wchart_t *P = L"ook";//L表示宽字符。

     

    当然,我们也不能直接这样用。而是要用 TEXT 宏

    用法如下 TCHAR *P = TEXT("ook");

    定义类似于下面这样。

    #ifdef UNICODE

    typedef wchar_t TCHAR

    #define TEXT(X)  L##X

    #else

    typedef char TCHAR

    #define TEXT(X)

    #endif

    这样就能正确对应了。

    总结一下编写支持ANSI/UNICODE编译的原码规则。

     

    #将文本串视为字符数组,而不是char数组或BYTE数组。(因为TCHAR的长度不固定)

    #将通用数据类型(TCHAR,PTSTR)用于文本字符和字符串

    #将显式数据类型(BYTE,PBYTE)用于字节,字节指针和数据缓存

    #将TEXT宏用于原义字符和字符串。

    #执行全局性替换(例如用PTSTR替换PSTR)

    #修改字符串运算问题。例如计算数组大小时,应该用sizeof(szBubffer)/szBuffer[0] ;

    此程序便支持ANSI/UNICODE,并且输出无异常。 可以将StringRevers_(pStr);屏蔽,将 //StringRevers(pStr);打开,并在ANSI/UNICODE下编译看效果。 另外,输出到控制台的结果,也说明了使用的字长不一样。。。

    关于用到的两个转换函数,可以查MSDN。

    总结完毕。。。打完收工。!!!!

  • 相关阅读:
    cPanel设置自定义404错误页
    jquery鼠标移入某区域屏蔽鼠标滚轮 滚动滚动条
    阻止子元素继承父元素事件(郁闷我一晚上的问题!)
    告别码农,成为真正的程序员
    PHP中数组合并的两种方法及区别介绍
    理解OAuth 2.0[摘]
    mysql之触发器trigger 详解
    ThinkPHP Where 条件中使用表达式
    linux下利用curl监控网页shell脚本
    XUtils 3 使用
  • 原文地址:https://www.cnblogs.com/qilinzi/p/1940490.html
Copyright © 2011-2022 走看看