• 11078阅读
  • 9回复

[提问]用QSettings写ini文件  乱码 [复制链接]

上一主题 下一主题
离线xiongyu
 

只看楼主 倒序阅读 楼主  发表于: 2010-07-08
— 本帖被 XChinux 从 Qt基础编程 移动到本区(2013-04-01) —
  1. QSettings *ConfigIni = new QSettings("D:\\a.ini",QSettings::IniFormat,0);    
  2. ConfigIni->setValue(tr("/管理/姓名"),"2222");


这样写进a.ini 中文全部变成%%%%之类的

要怎么做才能写入正确的中文。

已经
  1. QTextCodec::setCodecForTr(QTextCodec::codecForName("gb18030"));
为自己而已努力吧... 我的博客 http://xycode.org
离线xiongyu

只看该作者 1楼 发表于: 2010-07-08
各位大侠来帮帮我啊,我个大搜索引擎都去过了额。。

都解决不了啊。。
为自己而已努力吧... 我的博客 http://xycode.org
离线dbzhang800

只看该作者 2楼 发表于: 2010-07-08
这种问题还是多看Qt自带的manual吧

http://doc.qt.nokia.com/4.6/qsettings.html#setIniCodec

题外话:这么用中文应该不是个好主意,而此处还用 tr 包住就更不易理解了
离线xiongyu

只看该作者 3楼 发表于: 2010-07-09
手册我真的看了好多次了。

gb18030
UTF-8

我都试过了,就是中文不行。。
为自己而已努力吧... 我的博客 http://xycode.org
离线water_wf

只看该作者 4楼 发表于: 2010-07-09
呵呵,读出来看看不正确吗?
离线dbzhang800

只看该作者 5楼 发表于: 2010-07-09
Qt的manual不解决问题,不妨看看Qt的源码:

%QTDIR%\src\corelib\io\qsettings.cpp

重点看 函数
  1. bool QConfFileSettingsPrivate::writeIniFile(QIODevice &device, const ParsedSettingsMap &map)


特别注意该函数调用的另两个函数

  1. void QSettingsPrivate::iniEscapedKey(const QString &key, QByteArray &result)
  2. void QSettingsPrivate::iniEscapedString(const QString &str, QByteArray &result, QTextCodec *codec)


然后你会注意到,Section 与 Key 是不会采用 QTextCodec 进行编解码的,而 Value 会采用 QTextCodec 进行编解码
离线xiongyu

只看该作者 6楼 发表于: 2010-07-09
是啊,键值是中文正常。

段名和节点就是乱码了。

我就想解决这个问题额
为自己而已努力吧... 我的博客 http://xycode.org
离线xiongyu

只看该作者 7楼 发表于: 2010-07-09
  1. QString stringxy="/管理/姓名";
  2. QSettings *ConfigIni = new QSettings("D:\\utf.ini",QSettings::IniFormat);
  3. ConfigIni->setIniCodec(QTextCodec::codecForName("gb18030"));
  4. ConfigIni->setValue(stringxy,tr("中文"));


为自己而已努力吧... 我的博客 http://xycode.org
离线dbzhang800

只看该作者 8楼 发表于: 2010-07-09
引用第6楼xiongyu于2010-07-09 13:05发表的  :
是啊,键值是中文正常。
段名和节点就是乱码了。
我就想解决这个问题额


首先,这个不叫乱码,Qt设计上就是这么处理的(如果有兴趣,不妨认真看看源码中的函数)

题外:
所谓乱码,是写入和读出时编码不一致造成的。比如你的一个包含中文的文件采用的是utf8编码,当你用仅支持gbk的编辑器打开,看到乱七八糟的字符,那个叫乱码。
这儿显然没这个问题。

这儿只不过对除下面蓝字外的字符都进行了转义处理。
void QSettingsPrivate::iniEscapedKey(const QString &key, QByteArray &result)
{
    result.reserve(result.length() + key.length() * 3 / 2);
    for (int i = 0; i < key.size(); ++i) {
        uint ch = key.at(i).unicode();

        if (ch == '/') {
            result += '\\';
        } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')
                || ch == '_' || ch == '-' || ch == '.') {
            result += (char)ch;
        } else if (ch <= 0xFF) {
            result += '%';
            result += hexDigits[ch / 16];
            result += hexDigits[ch % 16];
        } else {
            result += "%U";
            QByteArray hexCode;
            for (int i = 0; i < 4; ++i) {
                hexCode.prepend(hexDigits[ch % 16]);
                ch >>= 4;
            }
            result += hexCode;
        }
    }
}


当然,如果你非要实现你的功能,你可以修改QSettings 的源码。最好的方法是 使用 QSettings 的manual提到的方式,去定义自己的format
  1. Format  QSettings::registerFormat ( const QString & extension, ReadFunc  readFunc, WriteFunc  writeFunc, Qt::CaseSensitivity  caseSensitivity = Qt::CaseSensitive )   [static]


离线xiongyu

只看该作者 9楼 发表于: 2010-07-10
谢谢楼上的。。。

节点都用英文了,有空再解决这个问题了
为自己而已努力吧... 我的博客 http://xycode.org
快速回复
限100 字节
 
上一个 下一个