跨平台中文编码乱码问题!utf-8-bom和utf-8!
首先在QT环境下有下面几个特点:
- 使用QT Creator 新建的源码文件,默认编码方式为无bom的utf-8.
- 在没有中文的时候,utf-8与utf-8 bom,源码都编译正常。
- 在有中文的时候,utf-8编译会报错,utf-8 bom编译正常。(因此qt creator需要自己设置如果是utf8则添加bom)
因此在win系统,qtcreator平台上,采用MSVC编译时,
- 代码的源码要用utf-8-bom,
- 并且需要显示中文时,要用qstring::fromlocal8bit包裹(我很奇怪为啥都用utf-8-bom编码了,源码的中文为啥还是不能正常解析正确,可能是msvc不识别utf-8-bom,所以默认源码里的字符串为local本地编码了(window上默认是gbk,linux默认是utf-8),就很冲突是吧,不采用utf-8-bom源码根本不能写中文(会标红),采用了又不能正确解析出来)。
- msvc默认源文件的中文为gbk。但是qstring处理时,会按utf-8解析,这样就会用utf-8解析gbk的,导致编码错误。所以需要用fromlocal8bit包裹。
- 而linux的默认系统编码为utf-8,可以不用fromlocal8bit包裹也能显示。
- 为啥能显示呢?因为qstring有转换机制,将utf-8转成了unicode,unicode只要是按正确的编码进行解析的,就能在界面显示。
用QFile读取文本文件时的乱码问题
1.考虑跨平台时,需要读取文本文件(不是源码)所有都要用utf-8无bom编码。
2.采用QFile(QIOdevice直接读取文件,返回字节流的方式)
QFile aFile(aFileName);
if (!aFile.exists()) //文件不存在
return false;
if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
//采用QFile:readALL获取字节流方式读取字符串
ui->textEditDevice->setPlainText(aFile.readAll());
这种方式有一些要注意的点:
- 如果一个文本文件是ansi编码,即本地编码,在win系统上,采用QIODevice::readAll()获取到的字节流,是按文本的编码将字符映射到字节序列得到的。如果直接将读到的字节序列QByteArray当作QString字符串来使用是不行的!因为QString是默认按UTF-8编码进行解析字节序列生成unicode的(QString真正使用的是unicode哦),而我们读到的字节序列是按ansi编码生成的!QString就会按UTF-8编码去解析一个ANSI格式的字节序列并转换成unicode编码使用!!导致获取到的值是乱码的!!!因此,需要使用QString::fromLocal8Bit来包裹一下,将其按本地编码转换成unicode!!!unicode才能在屏幕上显示的时候不是乱码!
- 同样的!如果一个文本文件是utf-8编码,那读取的的字节序列就是按utf-8编码生成的,在作为QString字符串使用时,就不需要用QString::fromLocal8Bit包裹(否则会按本地编码解析一个utf8编码的字节序列生成unicode,导致乱码),可以直接使用,因为QString是默认按UTF-8编码进行解析字节序列生成unicode。
3. 采用QFile(QTextStream aStream(&aFile); 用文本流读取文件)
QFile aFile(aFileName);
if (!aFile.exists()) //文件不存在
return false;
if (!aFile.open(QIODevice::ReadOnly | QIODevice::Text))
return false;
QTextStream aStream(&aFile); //用文本流读取文件
aStream.setAutoDetectUnicode(true); //自动检测Unicode,才能正常显示文档内的汉字
ui->textEditStream->setPlainText(aStream.readAll());
如果没有这一句aStream.setAutoDetectUnicode(true); ,将按本地编码读取字符流。
加段aStream.setCodec("UTF-8")也可以
下面这样直接全局设置也可以
int main(int argc, char *argv[])
{
//解决汉字乱码问题
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForLocale(codec); //解决汉字乱码问题
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}