`
suoyihen
  • 浏览: 1360435 次
文章分类
社区版块
存档分类
最新评论

Unicode以及字符集转换

 
阅读更多

曾经碰到一个问题,
项目需要支持日文操作系统,但是没有编译成unicode程序。
然后在一个解析用户输入路径的地方出问题了。
原因是日文的"表"这个汉字,日文编码格式下,低字节和反斜杠'/'编码一样,解析的时候把它当成路径的分隔符了。:-(
// 項: 8D 80 (Shift_JIS)
// 目: 96 DA (Shift_JIS)
// 表: 95 5C (Shift_JIS)
// /: 5C (Shift_JIS)

反思一下,如果要支持国际化,最正确也最简单的办法是都编译成Unicode程序。
当然这样就很有可能需要进行些字符集的转换,整理了4个函数。
还可以组合使用,比如要多字节字符串-->UTF8格式字符串,可以调用1)+3)。

1)当前系统编码的多字节字符串-->Unicode格式字符串


2)Unicode格式字符串-->当前系统编码的多字节字符串


3)Unicode格式字符串-->UTF8格式字符串


4)UTF8格式字符串-->Unicode格式字符串


补充1)
_UNICODE vs UNICODE
在学习UNICODE的过程中发现有两种关于UNICODE的宏定义: UNICODE和_UNICODE.

UNICODE:
这个宏主要是在Windows SKD中使用, 比如GetWindowText(), 定义了UNICODE以后将被定义为GetWindowTextW(UNICODE版本),否则被定义成GetWindowTextA(ANSI版本).

_UNICODE:
该宏一般用在C运行时库和MFC头文件中, 这时候函数_tcslen()将被映射为wcslen(), 反之被映射为strlen(). 至于在MFC中, 一般存在如下的定义:
#ifdef _UNICODE
#ifndef UNICODE
#define UNICODE
#endif
#endif

#ifdef UNICODE
#ifndef _UNICODE
#define _UNICODE
#endif
#endif
所以在MFC使用哪个都可以.

总结:两个都用上总不会有错的:)

补充2)
VC6中为了编译Unicode软件出了需要添加_UNICODE宏定义外,还需要增加一步:指定程序的入口位置。
否则程序将会发生如下错误:error LNK2001: unresolved external symbol _WinMain@16。
解决办法:在Project Settings > Entry-point symbol编辑框中输入wWinMainCRTStartup。

补充3)
C++比Unicode出生得早,所以最开始没有考虑Unicode支持,char类型是单字节的。
wchar_t实际上是typedef定义。
所以特别要注意防止下面错误。
CString sText = _T("123456789");
int nLength = sText.getLength() //i=9
CFile cFile;
......
cFile.Write(sText,sText.getLength());
这段代码再普通不过了,编译也不会有任何问题。但是实际上输出的内容将会是错误的。正确的代码应该如下:
CString sText = _T("123456789");
int nLength = sText.getLength() //i=9
CFile cFile;
......
cFile.Write(sText,sText.getLength()×sizeof(_TCHAR));

补充4)
Java设计的时候已经考虑了对unicode的支持,所以Java的char类型占用2个字节。
Java中如果要进行字符集转换就简单多了,写了个程序测试了一下。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics