0
点赞
收藏
分享

微信扫一扫

c++利用 STL解析ini 文件

ini文件是Initialization File的缩写,即初始化文件,通常存放的是一个程序的初始化信息,是Windows的系统配置文件所采用的存储格式,统管windows的各项配置。ini文件的后缀名不一定是.ini,也可以是.cfg、.conf或者是.tx*。

ini文件是技术人员经常用到的一种系统配置方法,如何读取和快速识别ini文件中的内容实现起来比较烦琐,而STL是一个很好的解决方法,省去了许多底层函数的编制。

ini文件格式示例如

c++利用 STL解析ini 文件_键值对

主要有三种元素:section、key和value。key-value也叫键值对,位于等号左右两侧。左侧叫做key,即关键码;右侧叫做值,它们是成对出现的。section是由中括号“[ ]”标识的。一个 ini 文件是由多个section组成的,一个section是由多个key-value键值对组成的。我们的任务就是把ini文件中的信息以一定的方式保存在程序结构中,代码如下所示。

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;

class MySection {
    string section;
    map<string, string>mapKey;
public:
    MySection(string section) {
        this->section = section;
    }
    bool AddKeyValue(string key, string value) {
        pair<string, string>p(key, value);
        mapKey.insert(p);
        return true;
    }
    void Show(ostream& os) {
        os << section << endl;
        for_each(mapKey.begin(), mapKey.end(), [&os](pair<string, string> p) {
            os << "\t" << p.first << "=" << p.second << endl;
            });
    }
};
class MySectionCollect {
    map<string, MySection>mapSection;
public:
    bool AddSection(string strSection) {
        pair<string, MySection>p(strSection, MySection(strSection));
        mapSection.insert(p);
        return true;
    }
    MySection* GetSection(string strSection) {
        map<string, MySection>::iterator it = mapSection.find(strSection);
        return &((*it).second);
    }
    void Show(ostream& os) {
        auto it = mapSection.begin();
        while (it != mapSection.end()) {
            ((*it).second).Show(os);
            it++;
        }
    }
};
class ReadIni {
    string strPath;
    MySectionCollect& collect;
public:
    ReadIni(string strPath, MySectionCollect& collect):strPath(strPath),collect(collect){}
    void Trim(string& s) {
        if (s != "") {        //find_first_not_of返回下标位置
            s.erase(0, s.find_first_not_of(" "));    //删除左空格
            if (s != "") {
                s.erase(s.find_last_not_of(" ") + 1);    //删除右空格
            }
        }
    }
    string GetSection(string strText) {
        strText.erase(0, strText.find_first_not_of("["));
        strText.erase(strText.find_last_not_of("]") + 1);
        return strText;
    }
    void GetPair(string strText, string& key, string& value) {
        int pos = strText.find("=");
        key = strText.substr(0, pos);
        value = strText.substr(pos + 1, strText.length() - pos - 1);
        Trim(key);
        Trim(value);
    }
    void Process() {
        string strLine = "";
        string strSection = "";
        string strKey = "";
        string strValue = "";

        MySection* pSection = NULL;
        ifstream in(strPath.c_str());
        while (!in.eof()) {
            getline(in, strLine);
            Trim(strLine);
            if (strLine == "")continue;
            if (strLine.at(0) == '[') {
                strSection = GetSection(strLine);
                collect.AddSection(strSection);
                pSection = collect.GetSection(strSection);//获取当前对象的key-value键值对
            }
            if (strLine.at(0) != '[') {    
                GetPair(strLine, strKey, strValue);
                pSection->AddKeyValue(strKey, strValue);
            }
        }
        in.close();
    }
};
int main() {
    string path = "d:\\data.ini";
    MySectionCollect collect;
    ReadIni ri(path, collect);
    ri.Process();
    collect.Show(cout);
    return 0;
}

c++利用 STL解析ini 文件_#include_02

从语义上来说,一个section由多个key-value键值对组成,一个ini文件由多个section 组成。因此前者与基本类MySection 相对应,后者与 MySection集合类MySectionCollect相对应。而 ReadIni是读ini文件类,主要功能是根据ini配置文件填充MySectionCollect 对象。

可以看出用map进行查询既简洁,速度又较vector、 list容器快,因此在 MySection,MySectionCollect类中有两个主要的map成员变量,而不是 vector,list成员变量。

举报

相关推荐

0 条评论