Qt 读取ini中文字符

Qt自带的读写ini的方法不支持中文,而且ini文件的格式也不是ansi。因此自己封装了一个读中文ini的类。
说明:本文档共含有4个函数,从前往后依次是读取所有函数(getAllINI),读取节点函数(getObjSection),读取键值对函数(getObjSectionIter)。
以读取文本的方式载入ini文件到一个字符串中,获取[关键字]的位置,再获取[关键字]之后第一个[的位置,截取这两个位置之间的字符串,就获得了一个节(Section)的内容,然后再通过搜索截取后的字符串的关键字“\r\n关键字=”右侧的字符串读取该键值。

头文件ReadINI.h

#ifndef READINI_H
#define READINI_H

#include <QObject>
#include <QFile>
#include <QVector>

struct IniIter
{
    QString key;
    QString value;
};

class ReadINI : public QObject
{
    Q_OBJECT
public:
    explicit ReadINI(QObject *parent = nullptr);
    ReadINI(QString objPath);
    ~ReadINI();

    /** 设置文件路径
     * @brief setObjPath
     * @param objPath
     */
    void setObjPath(const QString& objPath);

    /** 获取所有的key值与value值
     * @brief getAllINI
     * @return
     */
    QVector<IniIter> getAllINI() const;

    /** 获取所有节点
     * @brief getObjSection
     * @return
     */
    QStringList getObjSection() const;

    /** 获取节点下的所有键值对
     * @brief getObjSectionIter
     * @param objSection
     * @return
     */
    QVector<IniIter> getObjSectionIter(const QString& objSection) const;


private:
    void openFile();
    void getObjSectionList();
    void close();

private:
    /**
     * @brief m_path
     */
    QString      m_path;

    /**
     * @brief m_file
     */
    QFile        m_file;

    /**
     * @brief m_readalltext
     */
    QString      m_readalltext;

    /**
     * @brief m_ObjSectionList
     */
    QStringList  m_ObjSectionList;

    /**
     * @brief m_readINIMap
     */
    QVector<IniIter>    m_readINIIter;
};

#endif // READINI_H

.cpp 文件

#include "readini.h"

#include <QTextStream>

ReadINI::ReadINI(QObject *parent) : QObject(parent)
{

}

ReadINI::ReadINI(QString objPath)
{
    this->m_path = objPath;
    openFile();
}

ReadINI::~ReadINI()
{
    close();
}

void ReadINI::setObjPath(const QString &objPath)
{
    this->m_path = objPath;
    openFile();
}

QVector<IniIter> ReadINI::getAllINI() const
{
    QVector<IniIter> result;
    for(const QString& objSection : m_ObjSectionList)
    {
        QVector<IniIter> temp;
        temp = getObjSectionIter(objSection);
        for(auto iter = temp.begin(); iter != temp.end(); ++iter)
        {
            result.append(temp);
        }
    }
    return result;
}

QStringList ReadINI::getObjSection() const
{
    return m_ObjSectionList;
}

QVector<IniIter> ReadINI::getObjSectionIter(const QString &objSection) const
{
    QVector<IniIter> result;
    if(!m_file.exists())
        return result;

    int SectionFindStart = m_readalltext.indexOf(objSection);//[节点]为起始点
    int SectionFindEnd = m_readalltext.indexOf("[",SectionFindStart + 1);//下一个节点的"["为结束点
    QString SectionValue = m_readalltext.mid(SectionFindStart,SectionFindEnd-SectionFindStart);//获取节点内容
    // 匹配所有的key值
    int key_pos = 0;
    QStringList objKeyList;
    QRegExp rx("(\\\r\\\n)[\u4e00-\u9fa50-9]*(=)");
    while(key_pos != -1 && key_pos < SectionValue.size())
    {
        key_pos = rx.indexIn(SectionValue,key_pos);
        if(key_pos == -1)
            continue;
        QString key = rx.cap(0);
        key.replace(QRegExp("\r"), "");//替换掉换行符
        key.replace(QRegExp("\n"), "");//替换掉换行符
        key.replace(QRegExp("="), "");//替换掉换行符
        objKeyList.append(key);
        key_pos += key.size();
    }

    // 获取value
    for(const QString & key : objKeyList)
    {
        QString KeyValue;
        int KeyFindStart =SectionValue.indexOf("\r\n" + key + "=");//以"\r\n键值="作为条件匹配
        if( KeyFindStart != -1) //如果搜索到匹配的键值,则读取键值内容
        {
            KeyFindStart =SectionValue.indexOf("=",KeyFindStart);//以等号作为起始点
            int KeyFindEnd = SectionValue.indexOf("\r\n",KeyFindStart);//以等号后的换行符作为结束点
            KeyValue = SectionValue.mid(KeyFindStart + 1,KeyFindEnd - KeyFindStart-1);//截取键值
            KeyValue.replace(QRegExp("\r"), "");//替换掉换行符
            KeyValue.replace(QRegExp("\n"), "");//替换掉换行符
            IniIter iter;
            iter.key = key;
            iter.value = KeyValue;
            result.append(iter);
        }
    }
    return result;
}

void ReadINI::openFile()
{
    if(m_path == "")
        return ;
    m_file.setFileName(m_path);

    if(!m_file.open(QIODevice::ReadOnly))
        return ;

    QTextStream infile(&m_file);
    m_readalltext = infile.readAll();
    getObjSectionList();
    m_readalltext.append("\r\n[结尾字符串]\r\n");

}

void ReadINI::getObjSectionList()
{
    // 匹配所有的节点名称
    QRegExp rx("(\\[)[\u4e00-\u9fa5]*(\\])");
    int pos = 0;
    while(pos!=-1 &&  pos<m_readalltext.size())
    {
        pos = rx.indexIn(m_readalltext,pos);
        if(pos == -1)
        {
            continue ;
        }
        QString ObjSection = rx.cap(0);
        m_ObjSectionList.append(ObjSection);
        pos += ObjSection.size();
    }
}

void ReadINI::close()
{
    m_file.close();
}

测试代码:

    ReadINI readIni("E:/config.ini");
//    m_file = readIni.getAllINI();
    QStringList list = readIni.getObjSection();
    for(auto section : list)
    {
        QVector<IniIter> iter = readIni.getObjSectionIter(section);
        for(auto temp : iter)
        {
            qDebug()<<temp.key<<temp.value;
        }
    }
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 Linux 下使用 QT 读取中文ini 文件,需要注意文件编码的问题。如果 ini 文件使用 UTF-8 编码,那么使用 QSettings 类即可直接读取中文字符。如果 ini 文件使用其他编码方式,你需要根据实际情况设置编解码器。 以下是一个读取 GB2312 编码的 ini 文件的例子: ```c++ #include <QCoreApplication> #include <QDebug> #include <QSettings> #include <QTextCodec> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 创建 QSettings 对象,指定 ini 文件路径和格式 QSettings settings("/path/to/gb2312/file.ini", QSettings::IniFormat); // 设置编解码器为 GB2312 QTextCodec *gbkCodec = QTextCodec::codecForName("GB2312"); settings.setIniCodec(gbkCodec); // 读取 key 为 "用户名" 的值 QString username = settings.value("用户名").toString(); qDebug() << "用户名:" << username; // 读取 key 为 "密码" 的值 QString password = settings.value("密码").toString(); qDebug() << "密码:" << password; return a.exec(); } ``` 在这个例子中,我们首先创建了一个 QSettings 对象来读取 GB2312 编码的 ini 文件中的数据。然后,我们获取了 GB2312 编解码器,并将其设置为 ini 文件的编解码器。接着,我们通过 `value()` 方法读取指定 key 的值即可。 需要注意的是,如果你要读写的文本数据使用的编码方式不同于 GB2312 或 UTF-8,你需要根据实际情况调用相应的方法来设置编解码器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值