夸平台程序字符串的处理

来源:互联网 发布:firefly ubuntu 14.04 编辑:程序博客网 时间:2024/05/01 10:51
对于跨平台程序的开发来说,字符串处理是一个麻烦事。不但要熟悉不同OS平台的字符编码集,还要寻找统一的方式来处理字符串。


    1,支持Unicode
    要想程序支持多语言,Unicode是必须的,你一定不想看到你的程序在中文windows系统上打开一个韩文名字的文件时却无法加载。Unicode是一个字符集的概念,也就是说在Unicode标准中,全球所有语言的字符几乎都定义了对应的值。于是又有了Unicode集的实现问题,Unicode要表示完整需要32位的数值,而常用的字符用16位的数值就能表示。于是有了UTF8,UTF16,UTF32等字符编码实现方法,其中UTF8编码兼容ASCII集,且没有字节序问题,使得UTF8成为平台间字符交换的标准编码(如网络传输)。
    对于windows系统来说,内核采用了UTF16实现Unicode,而Mac和几乎所有Linux均采用UTF8。也就是说,windows常见的窄字符API底层要转化到宽字符API调用。


    2,char和wchar_t
    c++为我们提供了两种字符类型,但却没有定义两种类型的长度,更没有定义这两种类型的字符代表的编码。对于windows系统,wchar_t是16位,编码是ucs2-BE(对应UTF16);mac和linux为32位,编码是ucs4-BE(对应UTF32)。
    char则更加复杂。由于UTF8是变长编码(1-4个字节表示一个字符),可以用char来表示。windows平台则可以用char来表示native string,其编码又与locale有关。
    locale是c++提供的一个本地化策略集,locale帮助系统按不同的标准理解操作系统中的资源,比如字符串的编码。我们还可以通过facet来为locale指定具体的策略。locale对于字符串编码的用处在于:它告诉操作系统怎么理解char类型的字符串,比如char与wchat_t之间转换时。


    3,跨平台策略
    通过以上繁杂的概念,字符串跨平台处理的难度可想而知。对于Mac和Linux系统,规则总结起来倒很简单:UTF8。Mac和几乎所有的Linux系统(POSIX)内核编码均为UTF8,本身就是Unicode,我们用char就足够了,可以不涉及wchar_t,而且对于网络传输等应用来说也完全能够胜任,UTF8很完美。
    对于windows,如果涉及到char(native string)和wchar_t(UTF16)的转换就很麻烦(需要根据locale支持不同的转换方法),因此最好用wchar_t,避免native string。涉及到网络或平台字符串交换,就转换为UTF8字符串。考虑到和Mac,Linux兼容,如果是网络程序(字符串交换),可以考虑用UTF8表示字符串,涉及到操作系统API或IO的地方,再转换为wchar_t类型字符串。


    4,boost::filesystem
    字符串的跨平台很多时候是为了兼容文件系统操作,boost为我们提供了filesystem库,使用起来非常方便。具体可以参考:boost filesystem library。根据boost官方文档的描述,boost::filesystem::path路径对于字符编码的规则如下:
    path内部采用imbued locale对不同平台的字符串路径做解析并进行必要的编码转换,locale可以通过codecvt设置的facet修改;
    对于Mac OS X,path::value_type应该是char,默认的locale采用UTF8编码(可以推广到所有BSD系统);
    对于Windows(包括MinGW),path::value_type是wchar_t,默认UTF16编码。