分类: C/C++
2014-02-10 13:42:05
QTextCodec* gbk = QTextCodec::codecForName("GBK");
QTextCodec* utf8 = QTextCodec::codecForName("UTF-8");
codec可以把QString转换为自己的编码:
QByteArray ba = gbk->fromUnicode(QString);
char* c = ba.data();
codec也可以把外来的数据按自己的编码进行解码并转换成统一编码的QString:
QString s = gbk->toUnicode(char*);
总之乱码的根源就是以下两种可能的错误,第一种是输入时没有用正确的codec对数据源解码,第二种是输出时没有用正确的codec编码
非错误型乱码
一些操作系统是带有特定语言版本的,对外文的处理一般需要打好外文补丁,包括字符编码表和显示用的字体库等,如果没有打全补丁,则会出现显示乱码,但实际编码是正确的,仅仅是没有字体库导致。这种情况无需修正程序,给操作系统补充该语言的字体即可。
针对于QT4:
构造QString时需注意,如下书写形式:
QString("中文");
时,会根据全局设定函数
QTextCodec::setCodecForCStrings(QTextCodec* codec);
所设定的codec对引号内的数据进行解码。
QObject::tr("中文");
时,会根据全局设定函数
QTextCodec::setCodecForTr(QTextCodec* codec);
所设定的codec对引号内的数据进行解码。
针对于QT5:
取消了以下两个全局设定函数
QTextCodec::setCodecForCStrings(QTextCodec* codec);
QTextCodec::setCodecForTr(QTextCodec* codec);
内部默认为UTF-8解码,也就是说等效于内部调用了
QTextCodec* utf8 = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForCStrings(utf8);
QTextCodec::setCodecForTr(utf8);
这样一来,就要求外部引入的文本,都需要明确的utf8编码进入QString,比如源代码里的QString("中文"),源代码文件是utf8编码,这样就可以了,再比如读了一个文件或由通信方式接收,这个内容实际是GBK编码,就必须这样才行
QTextCodec* gbk = QTextCodec::codecForName("GBK");
QString s = gbk->toUnicode(char* readbuff);
关于locale:
这个概念是stdc++库的,指明了本地系统的地理和语言区域,用于支持国际化的程序判定locale后采取预期的行为,比如正确的语言显示和推送内容等。这个locale可由环境变量而来或可以按需设定
LANG=zh_CN
std::locale::setlocale()
因此对于应用程序是活的。locale是启动时根据运行环境设定好的,如没有特别需要最好不要修改。
对于QT而言,启动后会为系统locale选择合适的文本codec,无需再设定。比如想在console输入或输出一个特定语言的QString的话:
printf("%s\n", QString.toLocal8Bit().data()); // 不必考虑console的显示,会根据locale正确选择
scanf(buff); QString.fromLocal8Bit(buff); // 不必考虑console的编码,会根据locale正确选择
如果显示调用了
QTextCodec::setCodecForLocale(QTextCodec* codec);
这样就设定了指定的codec,此种情形效果是:在任何不知locale是什么的环境中,使用指定的文本codec。
QString::toLocal8Bit();
QString::fromLocal8Bit(char*);
使用的codec就变成了setCodecForLocale指定的codec。