跨平台C++软件开发中,由于不同操作系统对Unicode的支持差异,而导致的一些问题及解决方案
来源:互联网 发布:淘宝发布宝贝上传图片 编辑:程序博客网 时间:2024/04/29 02:40
跨平台C++软件开发中,由于不同操作系统对Unicode的支持差异,而导致的一些问题及解决方案。 收藏
1. 问题的提出。
1. 问题的提出。
各种各样的编码永远是软件开发者最为头痛的问题之一,Unicode为统一编码带来了希望。可是,就算是Unicode也不是百分百的完美,它只是完成了对各种语言编码的制定,而在具体的操作系统支持上,又分为UTF8,UTF16和UTF32好几个版本。比如,Windows系统支持的Unicode是UTF16,也就是每2个字节表示一个字符(还有一种称为代理的情况,容后讨论)。而Linux下默认支持的却是UTF32的Unicode标准,每4个字节才表示一个字符。
2. 实例说明
想象一下,假设您在Windows 系统下开发了一个软件,将一些文本数据用Unicode(UTF16)编码保存到一个文件,现在由于业务需要,您想将这个程序在Linux平台跑起来,会发生什么情况呢?
一般来说,您的代码在处理字符串资源时,会使用C/C++标准库的wchar_t数组或者std::wstring来保存字符串,使用wstrcpy,wstrlen或者std::string类提供的成员函数处理字符串,然后使用wfprintf或者std::wfstream进行字符串的读写。这部分代码好像没有问题,标准的C/C++ 函数,在整个软件移植时都不用修改。是的,代码词法和语法确实都没有问题,编译也能够通过。可是,程序运行的结果呢?根据上面的讨论,wchar_t在Windows平台下,,每个字符2个字节;而在linux平台下,每个字符4个字节。如果您的某个用户在Windows平台下保存一个字符串“Hello”到某个文件,然后另一个用户在Linux下打开这个文件,那么,他所得到会是什么呢?
Windows平台下用Unicode(UTF16)编码保存“Hello“到文件,实际写入的16进制串如下所示
H e l l o
4800 6500 6C00 6C00 6F00
形成一个串,00480065006C006C006F,写入文件。
在Linux系统下,程序将这个串当作UTF32读入后,结果是两个字符(最后2个字节6F00被舍弃)
0x00650048和0x006C006C,字符串长度是2,这显然不是希望的到的“Hello“。
Windows平台下用Unicode(UTF16)编码保存“Hello“到文件,实际写入的16进制串如下所示
H e l l o
4800 6500 6C00 6C00 6F00
形成一个串,00480065006C006C006F,写入文件。
在Linux系统下,程序将这个串当作UTF32读入后,结果是两个字符(最后2个字节6F00被舍弃)
0x00650048和0x006C006C,字符串长度是2,这显然不是希望的到的“Hello“。
3. 解决的办法
根据个人的经验,解决方案主要有以下2种:
根据个人的经验,解决方案主要有以下2种:
1. 由于产生平台不兼容的主要原因是平台之间使用的Unicode方案不统一,一个最为显而易见的解决办法就是选择使用某种操作系统的编码,在另一个平台上,使用自己的字符串保存和操作函数。一般推荐使用UTF16,具体原因请参考本人关于UTF16和UTF32的比较。决定好使用的编码方案后,还需要定义相应的操作函数,如字符串拷贝函数,比较函数等。一个偷懒的办法是把VC crt的部分代码Copy出来,什么wstrcpy,wstrlen,一个也不放过。在程序中进行字符串处理和存取时使用自己定义的方法,就可以避免平台差异带来的问题了。
而且,选择这种方案的一个更为重要的原因是,这个解决方案已经有大量的Open Source软件库可以直接使用,比如ICU(International Component for Unicode),libiconv等。
而且,选择这种方案的一个更为重要的原因是,这个解决方案已经有大量的Open Source软件库可以直接使用,比如ICU(International Component for Unicode),libiconv等。
2. 避开UTF16和UTF32,直接使用UTF8进行字符串的处理,因为各个平台对于UTF8的处理都是完全相同的。而且,UTF8和UTF16和UTF32使用的编码完全一样,只是内存表示的差异,有成熟的算法可以实现这3种编码的直接转换.以下是www.unicode.org官方的转换代码连接:http://www.unicode.org/Public/PROGRAMS/CVTUTF/。
当然,这种做法也有一定的不利因素,因为UTF8本身是一种可变长的编码方案,对于常见的英文,使用一个字节,对于中文,一般是3个字节。这种可变长的字符编码给一些操作带来不便。如取某个字符串的子串,就必须从头开始做遍历,然后一个一个字符进行计算,直到长度达到要求。而如果使用UTF16或者UTF32,简单的对数组进行索引就可以了(不考虑UTF16的代理机制,常见文字不会用到)。
当然,这种做法也有一定的不利因素,因为UTF8本身是一种可变长的编码方案,对于常见的英文,使用一个字节,对于中文,一般是3个字节。这种可变长的字符编码给一些操作带来不便。如取某个字符串的子串,就必须从头开始做遍历,然后一个一个字符进行计算,直到长度达到要求。而如果使用UTF16或者UTF32,简单的对数组进行索引就可以了(不考虑UTF16的代理机制,常见文字不会用到)。
关于UTF8,UTF16,UTF32的详细讨论可以参考www.unicode.org,也可以参考本人blog编码文件夹下的一些介绍性文字。
4. 参考文档
www.unicode.org,本文提及的所有资料都可以在unicode.org上找到。
http://oss.software.ibm.com/icu/,IBM的开源Unicode实现,可以完全替代操作系统提供的与编码和国际化相关的功能。
http://www.gnu.org/software/libiconv/, GNU的Unicode实现,集成在Linux操作系统中,但是库本身跨平台。
www.unicode.org,本文提及的所有资料都可以在unicode.org上找到。
http://oss.software.ibm.com/icu/,IBM的开源Unicode实现,可以完全替代操作系统提供的与编码和国际化相关的功能。
http://www.gnu.org/software/libiconv/, GNU的Unicode实现,集成在Linux操作系统中,但是库本身跨平台。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/dengyunze/archive/2004/10/16/139157.aspx
- 跨平台C++软件开发中,由于不同操作系统对Unicode的支持差异,而导致的一些问题及解决方案。
- 跨平台C++软件开发中,由于不同操作系统对Unicode的支持差异,而导致的一些问题及解决方案
- VS2013下由于字符集不同导致的C/S通信错误解决方案
- 不同软件版本及系统的差异导致的错误汇总
- android开发中遇到的一些问题及解决方案
- android中,由于图像处理不当而引起的OOM问题及其解决方案(一)
- android中,由于图像处理不当而引起的OOM问题及其解决方案(二)
- 由于OpenJDK1.6而导致的Oracle Linux6.x操作系统崩溃(crash)
- ionic-开发跨平台app的基本问题及解决方案
- java为什么可以实现跨平台(即实现一次编译,到处执行,此处的平台主要指不同的操作系统),而C/C++却不行?
- VC2005中C运行时库选择不当导致的链接问题及解决方案
- 对操作系统开发相关的一些问题的思考
- 关于VB中对Unicode的支持
- 关闭VC2005中对Unicode的支持
- android NDK中对C和C++的处理不同,导致使用方法不同
- Intellig IDEA中由于host绑定而引发的问题
- 破解由于异步执行而导致的JS插件未加载就使用的问题
- 软件开发中遇到的一些问题
- C++字符集问题终极分析(可解决乱码问题) 收藏
- c/c++中extern用来声明全局变量
- 关于六种windows media SDK的介绍【译】——2
- 尽量定义class形式的Function Object
- 解析C++中的内部连接与外部连接
- 跨平台C++软件开发中,由于不同操作系统对Unicode的支持差异,而导致的一些问题及解决方案
- 首要办到的
- 想成为真正的程序员,为什么不从linux开始呢?
- 谈谈SQL Server 2005中设置自动编号字段 【转】
- 明月寄相思
- 新的一年——新的计划
- java方法的重载
- 键盘上键的作用
- DOTNET面试概念题