注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

指南针的天空

你永远也看不到我最寂寞时候的样子,因为只有你不在我身边的时候,我才最寂寞。

 
 
 

日志

 
 

VC下的UNICODE编程  

2011-06-01 22:06:07|  分类: Visual C++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

为 vc 工程添加 Unicode Debug 和 Unicode Release

通过使用unicode编译,软件可以适应多种情况,如何在自己的工程中添加这两种编译方式呢?下面是一个简单的步骤
   
    1、新建一个工程;
   
    2、选择“Build->Configurations”菜单

    3、点击“Add”按钮,添加“Unicode Debug”-拷贝“win32 Debug”配置
        添加“Unicode Release”-拷贝“win32 Release”配置 ,然后点击“OK”

    4、选择“Project->Setting”菜单

    5、切换到“General ”TAB页

    6、修改 “Win32 Unicode Debug” 的 Intermediate Files 和 Output Files 为DebugU  

    7、修改 “Win32 Unicode Release” 的 Intermediate Files 和 Output Files 为ReleaseU  

    8、切换到“C++ ” Tab页

    9、从下拉列表框中选择 “Preprocessor”

   10、为 “Win32 Unicode Debug” 和 “Win32 Unicode Release” 分别添加_UNICODE 和 UNICODE variables


还要在link中,Category选output,将Entry-Point Symbol设为wWinMainCRTStartup

Rinrin 2005-10-9 07:39
 
忽然觉得忘了说了

程序中所有的字符串必须用TEXT()之类的宏括起来
这样UNICODE宏才有意义啊
呵呵^ ^

Gandalf 2005-10-23 03:53
 
Windows环境下Unicode编程总结[zt]

UNICODE环境设置


在安装Visual Studio时,在选择VC++时需要加入unicode选项,保证相关的库文件可以拷贝到system32下。

UNICODE编译设置:


C/C++, Preprocessor difinitions 去除_MBCS,加_UNICODE,UNICODE


在ProjectSetting/link/output 中设置Entry为wWinMainCRTStartup


反之为MBCS(ANSI)编译。

Unicode :宽字节字符集

1. 如何取得一个既包含单字节字符又包含双字节字符的字符串的字符个数?


可以调用Microsoft Visual C++的运行期库包含函数_mbslen来操作多字节(既包括单字节也包括双字节)字符串。


调用strlen函数,无法真正了解字符串中究竟有多少字符,它只能告诉你到达结尾的0之前有多少个字节。

2. 如何对DBCS(双字节字符集)字符串进行操作?


函数 描述


PTSTR CharNext ( LPCTSTR ); 返回字符串中下一个字符的地址


PTSTR CharPrev ( LPCTSTR, LPCTSTR ); 返回字符串中上一个字符的地址


BOOL IsDBCSLeadByte( BYTE ); 如果该字节是DBCS字符的第一个字节,则返回非0值

3. 为什幺要使用Unicode?


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


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


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


Windows 2000是使用Unicode从头进行开发的,如果调用任何一个Windows函数并给它传递一个ANSI字符串,那幺系统首先要将字符串转换成 Unicode,然后将Unicode字符串传递给操作系统。如果希望函数返回ANSI字符串,系统就会首先将Unicode字符串转换成ANSI字符 串,然后将结果返回给你的应用程序。进行这些字符串的转换需要占用系统的时间和内存。通过从头开始用Unicode来开发应用程序,就能够使你的应用程序 更加有效地运行。


Windows CE 本身就是使用Unicode的一种操作系统,完全不支持ANSI Windows函数


Windows 98 只支持ANSI,只能为ANSI开发应用程序。


Microsoft公司将COM从16位Windows转换成Win32时,公司决定需要字符串的所有COM接口方法都只能接受Unicode字符串。

4. 如何编写Unicode源代码?


Microsoft 公司为Unicode设计了WindowsAPI,这样,可以尽量减少代码的影响。实际上,可以编写单个源代码文件,以便使用或者不使用Unicode来 对它进行编译。只需要定义两个宏(UNICODE和_UNICODE),就可以修改然后重新编译该源文件。


_UNICODE宏用于C运行期头文件,而UNICODE宏则用于Windows头文件。当编译源代码模块时,通常必须同时定义这两个宏。

5. Windows定义的Unicode数据类型有哪些?


数据类型 说明


WCHAR Unicode字符


PWSTR 指向Unicode字符串的指针


PCWSTR 指向一个恒定的Unicode字符串的指针


对应的ANSI数据类型为CHAR,LPSTR和LPCSTR。


ANSI/Unicode通用数据类型为TCHAR,PTSTR,LPCTSTR。

6. 如何对Unicode进行操作?


字符集 特性 实例


ANSI 操作函数以str开头 strcpy


Unicode 操作函数以wcs开头 wcscpy


MBCS 操作函数以_mbs开头 _mbscpy


ANSI/Unicode 操作函数以_tcs开头 _tcscpy(C运行期库)


ANSI/Unicode 操作函数以lstr开头 lstrcpy(Windows函数)


所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。ANSI版本函数结尾以A表示;Unicode版本函数结尾以W表示。Windows会如下定义:


#ifdef UNICODE


#define CreateWindowEx CreateWindowExW


#else


#define CreateWindowEx CreateWindowExA


#endif // !UNICODE

7. 如何表示Unicode字符串常量?


字符集 实例


ANSI “string”


Unicode L“string”


ANSI/Unicode T(“string”)或_TEXT(“string”)if( szError[0] == _TEXT(‘J’) ){ }

8. 为什幺应当尽量使用操作系统函数?


这将有助于稍稍提高应用程序的运行性能,因为操作系统字符串函数常常被大型应用程序比如操作系统的外壳进程Explorer.exe所使用。由于这些函数使用得很多,因此,在应用程序运行时,它们可能已经被装入RAM。


如:StrCat,StrChr,StrCmp和StrCpy等。

9. 如何编写符合ANSI和Unicode的应用程序?


(1) 将文本串视为字符数组,而不是chars数组或字节数组。


(2) 将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。


(3) 将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。


(4) 将TEXT宏用于原义字符和字符串。


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


(6)修改字符串运算问题。例如函数通常希望在字符中传递一个缓存的大小,而 不是字节。这意味着不应该传递sizeof(szBuffer),而应该传递(sizeof(szBuffer)/sizeof(TCHAR)。另外,如 果需要为字符串分配一个内存块,并且拥有该字符串中的字符数目,那幺请记住要按字节来分配内存。这就是说,应该调用


malloc(nCharacters *sizeof(TCHAR)),而不是调用malloc(nCharacters)。

10. 如何对字符串进行有选择的比较?


通过调用CompareString来实现。


标志 含义


NORM_IGNORECASE 忽略字母的大小写


NORM_IGNOREKANATYPE 不区分平假名与片假名字符


NORM_IGNORENONSPACE 忽略无间隔字符


NORM_IGNORESYMBOLS 忽略符号


NORM_IGNOREWIDTH 不区分单字节字符与作为双字节字符的同一个字符


SORT_STRINGSORT 将标点符号作为普通符号来处理

11. 如何判断一个文本文件是ANSI还是Unicode?


判断如果文本文件的开头两个字节是0xFF和0xFE,那幺就是Unicode,否则是ANSI。

12. 如何判断一段字符串是ANSI还是Unicode?


用IsTextUnicode进行判断。IsTextUnicode使用一系列统计方法和定性方法,以便猜测缓存的内容。由于这不是一种确切的科学方法,因此 IsTextUnicode有可能返回不正确的结果。

13. 如何在Unicode与ANSI之间转换字符串?


Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串;函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串。

14. Unicode和DBCS之间的区别


Unicode 使用(特别在C程序设计语言环境里)“宽字符集”。「Unicode中的每个字符都是16位宽而不是8位宽。」在Unicode中,没有单单使用8位数值 的意义存在。相比之下,在“双位组字符集”中我们仍然处理8位数值。有些位组自身定义字符,而某些位组则显示需要和另一个位组共同定义一个字符。


处理DBCS字符串非常杂乱,但是处理Unicode文字则像处理有秩序的文 字。您也许会高兴地知道前128个Unicode字符(16位代码从 0x0000到0x007F)就是ASCII字符,而接下来的128个Unicode字符(代码从0x0080到0x00FF)是ISO 8859-1对ASCII的扩展。Unicode中不同部分的字符都同样基于现有的标准。这是为了便于转换。希腊字母表使用从0x0370到0x03FF 的代码,斯拉夫语使用从0x0400到0x04FF的代码,美国使用从0x0530到0x058F的代码,希伯来语使用从0x0590到0x05FF的代 码。中国、日本和韩国的象形文字(总称为CJK)占用了从0x3000到0x9FFF的代码。Unicode的最大好处是这里只有一个字符集,没有一点含 糊。



在VC6中,默认使用MBCS编码,即多字节字符;而VC8、VC7默认的是Unicode编码,实际就是支持大于0x80的ASCII码。这样,一个中文字可以表示为2个字节,GB2312就是这样表示的。


    VC6的默认安装是不带UNICODE库的,要在VC6中写UNICODE程序,必须安装CRT和MFC的Unicode库。要使你的程序支持 Unicode,要在你的项目属性中去掉"_MBCS"宏定义,增加"UNICODE"和"_UNICODE"两个宏定义。(注意,这两个都应该加上,因 为CRT和MFC使用UNICODE定义,而STL则使用_UNICODE)。

    如果你的程序是MFC的,则Unicode版MFC库的入口点是wWinMainCRTStartup。

    VS2005工程的默认字符集是Unicode。

    

   为了方便开发者,VC6中提供了Tchar.h,里面定义了一些宏用来帮助写两种编码都兼容的代码。

 

CRT中的相关函数在Tchar.h中都定义了相应的替代,基本是将str换成了_tcs,

比如:CRT中的unsigned int strlen(const char *)现在是unsigned int _tcslen(const TCHAR*),

在Uniocde时,将被替换为unsigned int _wcslen(const wchar_t)*,

而在MBCS时,会被替换为unsigned int _mcslen(const char*)。


看,写Unicode和MBCS兼容的代码挺容易的吧,我总结了一些替换规则
1 将char换成TCHAR (unsigned char必须去掉unsigned)
2 将str函数换成_tcs函数
3 将字符串常量定义加要_T("")宏
4 printf函数族必须修改为wprintf,不过要注意千万不要使用wprintf函数来解析char型
很多时候程序中既需要Unicode,又需要使用ASCII,这时需要用到操作系统的2个API
WideCharToMultiByte用来将Unicode字符串转化为MBCS的
MultiByteToWideChar用来将MBCS字符串转化为Unicode的
一些注意事项:
在Unicode编码下,sizeof没那么可靠了,memset( 0 sizeof())的习惯用法可能会出大错,改成memset(0sizeof()/szieof(TCHAR))就没事了,呵呵
在Unicode下,一个中文字符就是一个字符,len = strlen() / 2;这样可不行了
用VC6进行UNICODE编程
最近试图将自己的程序编译成Unicode版本,费了不少力气,相关内容整理如下,适用于VC6,但VC7、VC8应该也差不多的(后者新建项目缺省即按Unicode编译)。
1. 添加 UNICODE 和 _UNICODE 预处理定义
位置:Project Settings -> C/C++ -> Preprocessor definitions
添加了这两个定义后,MFC的一些内置类型如 TCHAR、CString 都将转为支持宽字符类型(wchar_t)
2. 使用宽字符相关类型,如:
char -> TCHAR、char * -> LPTSTR、const char * -> LPCTSTR
3. 对字符串常量使用 _T() 宏
4. 替换C库中的中字符串操作函数,如 strlen -> _tcslen、strcmp -> _tcscmp 等
类似的还有C库中字符串与数字的转换函数,如 atoi -> _ttoi、itoa -> _itot 等
5. 将 Project Settings -> link -> Output -> Entry Point 设为 wWinMainCRTSTartup
否则会有如下错误:
msvcrtd.lib(crtexew.obj) : error LNK2001: unresolved external symbol _WinMain@16
6. C++标准库中的string,有对应的宽字符版本wstring,两者均为basic_string的特化版本
可在StdAfx.h中:
#ifdef _UNICODE
#define tstring wstring
#else
#define tstring string
#endif
然后在代码中使用 tstring 即可,类似的还有 fstream/wfstream、ofstream/wofstream 等
7. 宽字符版本的英文字符仍可直接与整型值进行比较,如:
CString s = _T("ABC");
ASSERT(s[0] == 'A');
8. 对于仍需使用ANSI字符串的地方,如第三方类库的接口,仍可继续使用;如需进行Unicode字符串和ANSI字符串的互转换,可使用 MultiByteToWideChar 和 WideCharToMultiByte

  评论这张
 
阅读(298)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018