查看完整版本: [-- Qt读取中文文件乱码解决方案 4和5都支持 --]

QTCN开发网 -> Qt中文处理 -> Qt读取中文文件乱码解决方案 4和5都支持 [打印本页] 登录 -> 注册 -> 回复主题 -> 发表主题

cangyuegui 2015-11-25 09:57

Qt读取中文文件乱码解决方案 4和5都支持


读取
获得文件内容
  1. QByteArray getFileContent(const QString &file)
    {
        if (!QFile::exists(file))
        {
            qDebug()<<"ERROR, File "<<file<<" Not Exists !";
            return QByteArray(NULL);
        }

        QFile dstFile(file);

        if (!dstFile.open(QIODevice::Text | QIODevice::ReadOnly))
        {
            qDebug()<<"ERROR, File "<<file<<" Open Failure !";
            return QByteArray(NULL);
        }

        QByteArray res = dstFile.readAll();
        dstFile.close();
        return res;
    }


转码
  1. QString convertToSytemEncode(const QByteArray &srcString)
    {
        QTextCodec* pTextCodec = QTextCodec::codecForName("System");
        if (NULL == pTextCodec)
        {
            return "";
        }
        return pTextCodec->toUnicode(srcString);
    }




保存GB2312一样的
  1. QByteArray encodeToSytemCodec(const QString &srcString)
    {
        static QTextCodec * codec = QTextCodec :: codecForName ("System");
        if (NULL == codec)
        {
            return "";
        }
        QByteArray encodedString = codec-> fromUnicode (srcString);
        return encodedString;
    }

tips:
ps1 上面函数中的System只有qt4才支持这个编码,会根据系统不同而不同,window下则是gb2312编码.如果使用qt5请自行修改为gb2312.倒地支持哪些,请在assitant中自行查找
ps2 linux一般文档可能是utf-8,到底是什么编码qt不提供这个函数,无法确定的时候请用iconv自行判断
ps3 gb2312文本的代码中可以放中文注释,utf文件的话,有中文可能会导致编译错误.另外代码体中不能有任何中文,否则可能会引起无法预料的错误.
ps4 不要使用什么三句话解乱码这种狗屁方案,而且这种方案的话,qt5也用不了

博客里面 有比较粗略的函数
http://blog.csdn.net/fei17n/article/details/49887981

dbzhang800 2015-11-25 15:56
被你标题吸引进来的,看到你的内容和标题出入比较大,简单说两句。

你文中内容似乎只是在试图解决一个问题:简体中文Windows下读取gbk编码的文本文件,Linux下读取utf8编码的文本文件。(而这个,对大家来说,其实不是问题。中文乱码的根源和难点都不在这儿)

单单就Windows来说:

中文文本文件可以是GB18030 / Big5 / Utf8 / Utf16-be / Utf16-le / Utf32-be / Utf32-le 等编码保存的。
而Windows下的System编码是由区域和语言设置所决定的。只不过在简体中文系统下用的GBK / GB18030罢了

你后面提到的4点,基本看不懂。特别是ps3和ps4,你到底是在描述读文件,还是在描述你的源码文件呢? 感觉上,你在推荐在VS环境下使用gb2312作为源码文件,而且你没有用过其他国家和地区的Windows编译过你的代码。

cangyuegui 2015-11-25 18:23
被你标题吸引进来的,看到你的内容和标题出入比较大,简单说两句。

你文中内容似乎只是在试图解决一个问题:简体中文Windows下读取gbk编码的文本文件,Linux下读取utf8编码的文本文件。(而这个,对大家来说,其实不是问题。中文乱码的根源和难点都不在这儿)

第一:这两个只是个例子,实际上任何qt支持的编码都没问题,而且这个是codec插件做的,可以自己编写替换,所以可以做到任意编码都支持.

单单就Windows来说:

中文文本文件可以是GB18030 / Big5 / Utf8 / Utf16-be / Utf16-le / Utf32-be / Utf32-le 等编码保存的。
而Windows下的System编码是由区域和语言设置所决定的。只不过在简体中文系统下用的GBK / GB18030罢了

第二:这个文中有对立或者错误的地方么?

你后面提到的4点,基本看不懂。特别是ps3和ps4,你到底是在描述读文件,还是在描述你的源码文件呢? 感觉上,你在推荐在VS环境下使用gb2312作为源码文件,而且你没有用过其他国家和地区的Windows编译过你的代码。

第三:ps3属于tip,说明gb2312代码下,文本注释中写入中文,是安全的,而其他编码,是可能导致编译错误的.这段描述的是源代码文件.
顺便也说了不要使用这个方案:QStringLiteral("中文")(部分编码下这样的代码可能引起编译错误,而且和cpp文件本身的编码有关系,不通用,建议使用tr+qm)

第四:用哪个国家的windows编译代码根本不是问题,vs是可以手动调编码的,调了gb2312一样认.

第五:ps4是指不要使用这个方案
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
解决中文乱码问题,但是QT5却对以上函数中的两个已经不支持。
这个方案,在非中文windows下面真的会出问题,而且几乎任意非window平台都会出问题.


最后:乱码的根源是编码不一致.qt使用的是unicode,但是系统里面的文件指不定什么的.对于未知文本文件,文中解决方案是,使用iconv判断.
对于数据库里面产生的乱码,通常是两种问题
1.数据库内部做到编码转换
2.数据库内部存储的不是unicode,但是读取出来后未做转码处理

对于1 只能自求多福,除非摸清楚他怎么转的.
对于二,转个码就行了.



dbzhang800 2015-11-25 22:12
首先:你的标题和贴中代码 都是说 读取中文文件乱码的解决方案。这和你tips中提到的C++源码采用何种编码,是两个既然不同的问题。

第一:这两个只是个例子,实际上任何qt支持的编码都没问题,而且这个是codec插件做的,可以自己编写替换,所以可以做到任意编码都支持.


Qt肯定可以读取任何它支持的编码的中文文件,这没人否认。但是乱码根源在于,你不知道读取的中文文件是何种编码。


第二:这个文中有对立或者错误的地方么?


你首帖中说的是:window下则是gb2312编码。事实上只有简体中文Windows下如此

第三:ps3属于tip,说明gb2312代码下,文本注释中写入中文,是安全的,而其他编码,是可能导致编译错误的.这段描述的是源代码文件.
顺便也说了不要使用这个方案:QStringLiteral("中文")(部分编码下这样的代码可能引起编译错误,而且和cpp文件本身的编码有关系,不通用,建议使用tr+qm)


呵呵,我是提倡用tr+qm的,但是提倡并不能解决问题。

你这儿描述的东西,只是你在简体中文windows下用VS2005及以上版本时,看到的一种表象。如果你知道了出错原因是什么,问题自然就明朗了。

gb2312远远没有你想象的好用。

第四:用哪个国家的windows编译代码根本不是问题,vs是可以手动调编码的,调了gb2312一样认.


说实话,这个似乎有点意思。VS下C++的编译器是 cl.exe,我还真不知道它有可以控制C++源码文件编码的选项。

第五:ps4是指不要使用这个方案
QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForTr(QTextCodec::codecForName("GBK"));
解决中文乱码问题,但是QT5却对以上函数中的两个已经不支持。
这个方案,在非中文windows下面真的会出问题,而且几乎任意非window平台都会出问题


嗯,我应该算是该用法强烈的抵制者(之一)吧。但在Qt4时期,网络上国内这种错误用法太多了。

不过,平心而论,直接用GBK这种还算是稍微好的了(比system那种好多了)。而且在非windows平台下,也不会有多大问题。

最后:乱码的根源是编码不一致.qt使用的是unicode,但是系统里面的文件指不定什么的.对于未知文本文件,文中解决方案是,使用iconv判断.


乱码的根源是不知道编码,而不是不一致。
对于一个文本文件来说,如果不知道它的编码,理论上是猜不出它的编码的,任何工具都没有用。


cangyuegui 2015-11-26 09:27
dbzhang800:首先:你的标题和贴中代码 都是说 读取中文文件乱码的解决方案。这和你tips中提到的C++源码采用何种编码,是两个既然不同的问题。
乱码的根源是不知道编码,而不是不一致。
....... (2015-11-25 22:12) 

那个system只是个例子啊

iconv可以判断出绝大部分编码,就想文本编辑器和notepad++打开文本一般不会乱码一样
但是并不是万能的

著名的 "联通" 乱码,这种是无能无力的.

代码中混入中文编译错误的原因,是因为编译器一般会把源码当做单字节读取,会把中文读成乱七八糟的东西.

不过题目确实不是很严谨

dbzhang800 2015-11-26 10:17
VS的的问题出在,Windows内部早就是unicode了,但是它又不愿意放弃和老旧代码的兼容性。从VS2005开始,如果源码文件不带BOM,它会默认你用的本地字符集,而且在编译正式开始前,它内部先将源码文件解码成unicode,而后进行处理。具体到简体中文Windows下,就是它会用GBK去解码你的源文件,而不管你实际用的是GBK/utf8/还是其他编码。

而有意思之处在于,用gbk解码utf8或其他编码文件,很多时候是可以成功的,尽管结果是乱的。

VS复杂之处在于:VS2003/2005/2008/2010/2012 ,行为各不相同。好在Qt5选定了默认utf8,使得问题可以简化很多。

cangyuegui 2015-11-26 14:58
dbzhang800:VS的的问题出在,Windows内部早就是unicode了,但是它又不愿意放弃和老旧代码的兼容性。从VS2005开始,如果源码文件不带BOM,它会默认你用的本地字符集,而且在编译正式开始前,它内部先将源码文件解码成unicode,而后进行处理。具体到简体中文Windows下,就是它会用GBK去解码你的 .. (2015-11-26 10:17) 

岂止行为不一样

语法都不一样


查看完整版本: [-- Qt读取中文文件乱码解决方案 4和5都支持 --] [-- top --]



Powered by phpwind v8.7 Code ©2003-2011 phpwind
Gzip disabled