字符集问题处理

C++error C2664: XXX不能将参数1从“CString”转换为“const char *(这一类问题基本上都是字符集格式不同而引起的)

VC6中,默认使用MBCS编码,即多字节字符,实际就是支持大于0x80ASCII码。这样,一个中文字可以表示为2个字节,GB2312就是这样表示的。

VC6的默认安装是不带UNICODE库的,要在VC6中写UNICODE程序,必须安装CRTMFCUnicode库。

要使你的程序支持Unicode,要在你的 项目-->属性 去掉"_MBCS"宏定义,增加"UNICODE""_UNICODE"两个宏定义。(注意,这两个都应该加上,因为CRTMFC使用UNICODE定义,而STL则使用_UNICODE

如果你的程序是MFC的,则UnicodeMFC库的入口点是wWinMainCRTStartup

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

类型

一般文本数据类型名称_UNICODE_MBCS未定义_MBCS _UNICODE已定义

_TCHAR char char wchar_t
_TINT int int wint_t
_TSCHAR signed char signed char wchar_t
_TUCHAR unsigned char unsigned char wchar_t
_TXCHAR char unsigned char wchar_t
_T 或 _TEXT 无效(由预处理器移除)(将后面的字符或字符串转换成相应的 Unicode 形式)

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*)

看,写UnicodeMBCS兼容的代码挺容易的吧,我总结了一些替换规则

char换成TCHAR (unsigned char必须去掉unsigned)

str函数换成_tcs函数

将字符串常量定义加要_T("")

4 printf函数族必须修改为wprintf,不过要注意千万不要使用wprintf函数来解析char

很多时候程序中既需要Unicode,又需要使用ASCII,这时需要用到操作系统2API

WideCharToMultiByte用来将Unicode字符串转化为MBCS

MultiByteToWideChar用来将MBCS字符串转化为Unicode

一些注意事项:

Unicode编码下,sizeof没那么可靠了,memset( 0 sizeof())的习惯用法可能会出大错,改成memset(0sizeof()/szieof(TCHAR))就没事了,呵呵

Unicode下,一个中文字符就是一个字符,len = strlen() / 2;这样可不行了



VC6进行UNICODE编程

最近试图将自己的程序编译成Unicode版本,费了不少力气,相关内容整理如下,适用于VC6,但VC7VC8应该也差不多的(后者新建项目缺省即按Unicode编译)。

1. 添加 UNICODE 和 _UNICODE 预处理定义

位置:Project Settings -> C/C++ -> Preprocessor definitions

添加了这两个定义后,MFC的一些内置类型如 TCHARCString 都将转为支持宽字符类型(wchar_t

2. 使用宽字符相关类型,如:

char -> TCHARchar * -> LPTSTRconst char * -> LPCTSTR

3. 对字符串常量使用 _T() 

4. 替换C库中的中字符串操作函数,如 strlen -> _tcslenstrcmp -> _tcscmp 

类似的还有C库中字符串与数字的转换函数,如 atoi -> _ttoiitoa -> _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/wfstreamofstream/wofstream 

7. 宽字符版本的英文字符仍可直接与整型值进行比较,如:

CString s = _T("ABC");
ASSERT(s[0] == 'A');

8. 对于仍需使用ANSI字符串的地方,如第三方类库的接口,仍可继续使用;如需进行Unicode字符串和ANSI字符串的互转换,可使用 MultiByteToWideChar 和 WideCharToMultiByte

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值