posts - 28, comments - 179, trackbacks - 0, articles - 1
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

字符集相关问题

Posted on 2007-05-30 16:54 chemz 阅读(5770) 评论(14)  编辑 收藏 引用 所属分类: C++
                                 字符集相关问题
    字符集目前有两个大的类别:本地字符集和国际字符集,其中每一类别的字符集又有多个
不同的字符编码实例。比如:本地字符集中基本上对于每一个不同的地区和国家就会形成一个
属于自己的字符集(ascii, latin-1, chs等),国际字符集中同样包括多种不同的编码方案
(utf8, utf16等)。
    那么在C/C++程序中如何完成上述字符集之间的转换工作呢?分成两种情况:
    1. 通过const char *cstr使用开发环境中的编辑器输入字符串常量"中国",如下:
            const char *cstr = "中国";
       这样一来cstr所指向的字符串内存中保存的则是本地字符编码下所形成的字符串,也
       就是说,上面的cstr中存储着chs字符编码集中的字符;
    2. 通过const wchar_t *wstr使用开发环境中的编辑器输入字符串常量"中国",如下:
            const wchar_t *wstr = L"中国";
       这样一来wstr所指向的字符串内存中保存的则是国际字符编码(在VC++下是ucs2,
       在gcc下是ucs4)下所形成的字符串,也就是说,上面的wstr中存储着utf16字符编
       码集中的字符;
    那么如何将cstr转换成为wstr呢?可以通过C语言中的标准转换函数mbstowcs来完成该工
作,此时需要注意的是如果直接使用mbstowcs进行转换会得到一个错误的结果,并不能成功
的完成转换成为国际宽字符的要求,这是为什么呢?在C/C++语言标准中定义了其运行时的
字符集环境为"C",也就是ASCII字符集的一个子集,那么mbstowcs在工作时会将cstr中所包
含的字符串看作是ASCII编码的字符,而不认为是一个包含有chs编码的字符串,所以他会将
每一个中文拆成2个ASCII编码进行转换,这样得到的结果就是会形成4个wchar_t的字符组成
的串,那么如何才能够让mbstowcs正常工作呢?在调用mbstowcs进行转换之间必须明确的告
诉mbstowcs目前cstr串中包含的是chs编码的字符串,通过setlocale( LC_ALL, "chs" )函数
调用来完成,需要注意的是这个函数会改变整个应用程序的字符集编码方式,必须要通过重
新调用setlocale( LC_ALL, "C" )函数来还原,这样就可以保证mbstowcs在转换时将cstr中
的串看作是中文串,并且转换成为2个wchar_t字符,而不是4个。


Feedback

# re: 字符集相关问题  回复  更多评论   

2007-05-30 20:47 by 小明
const wchar_t *wstr = "中国";

这样写不合法吧
const wchar_t *wstr = L"中国";

# re: 字符集相关问题  回复  更多评论   

2007-05-31 09:14 by chemz
非常感谢指出,书写时漏了L,谢谢!

# re: 字符集相关问题  回复  更多评论   

2007-05-31 11:00 by walkspeed
看来有人也研究过的也。

# re: 字符集相关问题  回复  更多评论   

2007-06-04 14:32 by 看图软件
研究下

# re: 字符集相关问题  回复  更多评论   

2007-06-26 21:17 by Jerry
请教一下,在Solaris操作系统下中文字符串使用的是什么字符集。
我在Solaris下用setlocale( LC_ALL, "chs" ),然后将字符串转换成unicode
得到错误结果,后来发现在solaris里面就没有"chs"这种编码方式,请问我怎样才能正确转换

# re: 字符集相关问题  回复  更多评论   

2007-06-27 08:51 by chemz
我在搞solaris的时候也遇到过这个问题,我所在的环境是solaris9和10对于8我不太清楚。是这样的,在solaris的操作系统安装光盘中有一张单独的Languages语言支持光盘,必须要选择安装对应的字符集支持,如果要显示中文还必须要切换操作系统的当前语种到中文(任意一种中文都没有问题,最好采用GB18030,否则会出现有些生僻的字没有编码的问题),这样就可以转换和显示了。对于solaris8没有试过,因为比较老了。

# re: 字符集相关问题  回复  更多评论   

2007-06-27 09:27 by Jerry
谢谢chemz
但是我在solaris下locale -a 查了一下他里面支持的中文字符集有
zh,zh_CN.EUC,zh.GBK,zh.UTF-8,我一个个试过了,但是都不正确转换,是不是真的需要另外加中文字符集,不清楚在solaris下面是不是真的有“chs”的字符集

# re: 字符集相关问题  回复  更多评论   

2007-06-27 10:27 by chemz
你用的什么编译器,GNU还是Sun的?

# re: 字符集相关问题  回复  更多评论   

2007-06-27 11:53 by Jerry
Sun 的CC编译器,

# re: 字符集相关问题  回复  更多评论   

2007-06-27 12:05 by chemz
不好意思我没有用过Sun的CC,凡是在Unix环境下开发我们都用统一的GNU gcc编译器集合,这样会比较好移植。

# re: 字符集相关问题  回复  更多评论   

2008-06-21 10:51 by 数字柔情
我在LINUX企业版5上实验了上面代码,编译时这句const wchar_t *wstr = L"中国";报错converting to execution character set:无效或不完整的多字节字符或宽字符。
是怎么回事啊,LINUX下不能把中文转成UNICODE吗?那怎么用。

# re: 字符集相关问题  回复  更多评论   

2008-06-22 13:55 by chemz
楼上的需要注意你可能在写const wchar_t *wstr = L"中国";这句话时引号是个中文的,所以才会有问题。

# re: 字符集相关问题  回复  更多评论   

2008-09-28 08:49 by soli

我怎么知道我的字符串中是什么编码呢?

比如:

m_ctrlEdit.GetWindowText(m_strEdit);

此时m_strEdit中是什么编码的字符串呢?

# re: 字符集相关问题  回复  更多评论   

2010-07-15 09:31 by hzpfly
如果中英文混排的情况如何转换成宽字符呢?
const char* str = "I 服了 You";

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理