• 14811阅读
  • 11回复

[提问]QSettings写入包含中文内容的INI文件错误 [复制链接]

上一主题 下一主题
离线la_fisher
 

只看楼主 倒序阅读 楼主  发表于: 2010-11-29
— 本帖被 XChinux 从 Qt基础编程 移动到本区(2013-04-01) —
代码如下:(代码文件的编码为UTF8


#include <QtCore/QCoreApplication>
#include <QSettings>
#include <QTextCodec>
#include <QFile>
#include <QSettings>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    char chContent[256] = {0};
    strcpy(chContent,"[1]I中文测试");
    QTextCodec* utf8 = QTextCodec::codecForName("UTF-8");
    QTextCodec* gbk = QTextCodec::codecForName("GBK");
    QSettings qset("D:\\test.ini",QSettings::IniFormat);    
    qset.setIniCodec(gbk);
    QString strx = utf8->toUnicode(chContent);
    QString strgbk = gbk->fromUnicode(strx);
    qset.setValue("Remark/number",strgbk);
  
    return a.exec();
}

写完之后只见英文部分。不知道是什么原因啊
离线dbzhang800

只看该作者 1楼 发表于: 2010-11-29
暴露的问题不少,一个一个来吧:

不妨解释一下:
QString strgbk = gbk->fromUnicode(strx);

是在做什么?
离线roywillow

只看该作者 2楼 发表于: 2010-11-29
很想知道为什么不直接用QString::fromLocale8Bit呢……
专业维修核潜艇,回收二手航母、二手航天飞机,大修核反应堆,拆洗导弹发动机更换机油,无人侦察机手动挡改自动,航天飞机保养换三滤,飞碟外太空年检 ,各型号导弹加装迎宾踏板,高空作业擦洗卫星表面除尘、打蜡及抛光,东风全系列巡航导弹。并提供原子对撞机。量大从优,有正规发票。
离线la_fisher

只看该作者 3楼 发表于: 2010-11-30
回 1楼(dbzhang800) 的帖子
这个语句是把Unicode转换为GBK编码。最初的程序没有这一句,后来为了测试,我加的。去掉这个结果也是一样的。
离线la_fisher

只看该作者 4楼 发表于: 2010-11-30
回 2楼(roywillow) 的帖子
我不知道你给我的这一句起什么作用?是把GBK转换为UNICODE吗?

我是要写入GBK,这个语句没什么用哦。
离线la_fisher

只看该作者 5楼 发表于: 2010-11-30
我的想法:代码编辑器中编辑的文件是UTF-8格式的,我用utf8编码器将其转换为UNICODE,然后再用gbk编码器转换为GBK编码,再写入GBK编码的ini文件。

当然那了,能更简单就更好了,可是简单的方法我都试过,都没用。
离线la_fisher

只看该作者 6楼 发表于: 2010-11-30
    最原始的代码是这样子的,中文无法写入,内容中只有前边几个字母
    char chContent[256] = {0};
    strcpy(chContent,"[1]I中文测试");
    QTextCodec* gbk = QTextCodec::codecForName("GBK");
    QSettings qset("D:\\test.ini",QSettings::IniFormat);    
    qset.setIniCodec("GBK");
    qset.setValue("Remark/number",gbk->fromUnicode(chContent));
离线dbzhang800

只看该作者 7楼 发表于: 2010-11-30
引用第5楼la_fisher于2010-11-30 08:01发表的  :
我的想法:代码编辑器中编辑的文件是UTF-8格式的,我用utf8编码器将其转换为UNICODE,然后再用gbk编码器转换为GBK编码,再写入GBK编码的ini文件。
当然那了,能更简单就更好了,可是简单的方法我都试过,都没用。

但是你贴的代码给人的感觉是,你是在胡乱测试。最基本的概念:提utf-8或gbk时,指的是字节流(byte);QString中是unicode。你应该坚持unicode,只在I/O时涉及编码转换。

就拿我前面给你提出的代码来说(strx和strgbk都是unicode,Unicode到Unicode有什么可转换的??):

QString strgbk = gbk->fromUnicode(strx);

* 一个字符串先被编码成 gbk,(存放在QByteArray) (编码动作)
* 用该QByteArray 构造了一个字符串                   (解码动作)
  * 如果转换规则是gbk(当然你这儿不是),这条语句相当于什么编解码动作都没做 QString strgbk(strx)
* 如果转换规则不是gbk,那这样的代码就...
离线dbzhang800

只看该作者 8楼 发表于: 2010-11-30
引用第6楼la_fisher于2010-11-30 08:09发表的  :
    最原始的代码是这样子的,中文无法写入,内容中只有前边几个字母
    char chContent[256] = {0};
    strcpy(chContent,"[1]I中文测试");
    QTextCodec* gbk = QTextCodec::codecForName("GBK");
    QSettings qset("D:\\test.ini",QSettings::IniFormat);    
.......

好吧,我接1楼告诉你第二个问题。你告诉大家你的源码是utf8编码不能有效说明问题。

从你的内容中出现盘符可知你用的windows。

如果你用的带BOM的utf8,且用的MSVC,那么 "中文测试" 是会被编译器转码为 gbk 编码,看来你这段代码是基于这个写的。

但是,如果是不带BOM的utf8或者用的是MinGW编译器,那么 "中文测试" 这样的代码是 utf8编码,而不是gbk编码。
离线la_fisher

只看该作者 9楼 发表于: 2010-11-30
问题已经解决了,但是还是不太明白原因。先说下我的环境:

目前这个程序是在WIndows下用QtCreator编译的,编译环境是MinGW编译器。
(这样的话,如果我的文件选择了UTF-8编码,是否可以确定我的代码文件中所有内容为UTF-8编码?)

以后程序回到Linux编译运行,但是程序使用到的磁盘文件必须使用GBK编码(因为文件最终不仅在Linux下使用,也可能在Windows下使用)。

现在的代码如下:
    char chContent[256] = {0};
    strcpy(chContent,"[1]I中文测试");
    QTextCodec* utf8 = QTextCodec::codecForName("UTF-8");
    QSettings qset("D:\\test.ini",QSettings::IniFormat,0);    
    qset.setIniCodec("GBK");
    qset.setValue("Remark/number",utf8->toUnicode(chContent));
写入成功。疑惑的地方在于:
我设置了INI文件编码为GBK,而写入的字符串编码是UNICODE,是不是QSettings类在写入INI时,或者写入INI之后做了编码转换?
QSettings的setValue方法是不是仅接受UNICODE编码?

我再进一步测试下。

离线dbzhang800

只看该作者 10楼 发表于: 2010-11-30
QString 就是unicode 字符串,当你提gbk或utf8时指的是字节流,最好就直接不认为它是字符串。

文件(QByteArray、char*) 读进 QString ,属于 Input 操作,属于 decode
QString 写入文件(QByteArray、char*),属于 Output 操作 ,属于 decode

相关东西不想说了:
* http://hi.baidu.com/cyclone/blog/item/9d7293130e5a498d6538dbf1.html
* http://hi.baidu.com/cyclone/blog/item/80a0793140fd3814eac4af7d.html
* http://hi.baidu.com/cyclone/blog/item/e48c76099b002ca22eddd4c3.html
* http://hi.baidu.com/cyclone/blog/item/1bcb5edfed60d20348540320.html
离线la_fisher

只看该作者 11楼 发表于: 2010-11-30
明白了。多谢
dbzhang800
快速回复
限100 字节
 
上一个 下一个