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;
}
}