首页 > 编程语言 >c++利用 STL解析ini 文件

c++利用 STL解析ini 文件

时间:2024-02-05 16:31:31浏览次数:42  
标签:value string STL section c++ strText ini key

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 文件_配置文件_02

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

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

标签:value,string,STL,section,c++,strText,ini,key
From: https://blog.51cto.com/u_16491666/9610680

相关文章

  • C++中的typedef和define的区别
    我们来看看typede和define的区别define是C++中用来定义宏的,也就是宏定义用的,宏在代码中就是纯粹进行简单的替换,这个替换过程不是在C++的编译过程中进行的,而是在这之前的预处理过程中就已经完成了.因为它不是在编译过程中进行,所以如果有潜在的错误,很难发现.typedef说白了,就是起......
  • c++生成随机数
    产生随机数的叫随机数生发器生成随机数constunsignedzseed=time(0);voidsolve(){ //随机数生发器 mt19937_64m{zseed}; //种子 rep(i,1,5) cout<<m()<<endl; return;}重排序列constunsignedzseed=time(0);mt19937_64zgen{zseed};voidsolve(){ ve......
  • springboot之ImportBeanDefinitionRegistrar动态注入
    SpringBoot中的使用在SpringBoot内置容器的相关自动配置中有一个ServletWebServerFactoryAutoConfiguration类。该类的部分代码如下:@Configuration(proxyBeanMethods=false)@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)@ConditionalOnClass(ServletRequest.class)@Con......
  • 从C向C++8——多态
    一.多态基础面向对象程序设计语言有封装、继承和多态三种机制,这三种机制能够有效提高程序的可读性、可扩充性和可重用性。“多态(polymorphism)”指的是同一名字的事物可以完成不同的功能。多态可以分为编译时的多态和运行时的多态。前者主要是指函数的重载(包括运算符的重载)、对重载......
  • c++11的左值 右值的笔记
    在C++11的程序中,所有的值必须属于左值,将亡值,纯右值之一。将忘值则是c++11新增的跟右值引用相关的表达式,这样表达式通常是将要被移动的对象(以为他用),比如返回右值引用T&&的函数返回值,std::move的返回值,或者转换为T&&的类型的转换函数的返回值。而剩余的,可以标识函数、对象的值都属......
  • 在K8S中,Minikube、Kubectl、Kubelet是什么?
    在Kubernetes(简称K8s)生态系统中,Minikube、kubectl和kubelet是三个不同的组件,各自扮演着不同的角色:Minikube:Minikube是一个工具,用于在单个节点上部署一个本地的Kubernetes集群。这对于开发者在本地开发环境进行Kubernetes应用测试和调试非常有用。它能够在个人计算机上启动一个......
  • C++类和对象
    1.类和对象1.1声明类classPerson{private:stringname;intage;};1.2作为类实例的对象1.3使用句点运算符访问成员1.4使用指针运算符(->)访问成员2.关键字public与private3.构造函数3.1构造函数重载3.2默认构造函数:只要不需要......
  • C++CLI 析构函数和终结器理解
    测试类:#pragmaoncerefclassHello{public:Hello();~Hello();!Hello();};/***************/#include"Hello.h"Hello::Hello(){System::Console::WriteLine("构造函数!");}Hello::~Hello(){System::Console::WriteLi......
  • C++ Primer 学习笔记 PartI C++基础
    Ch1开始略这一章包含控制流,条件,循环,注释,标准IO等内容。对于C语言/ACMC+STL中常见数值的内容不再赘述,仅总结较为不熟悉的内容。PartIC++基础CH2变量和基本类型2.1基本内置类型2.1.1算术类型2.1.1类型转换向unsigned赋超出范围的值,结果取余,对于signed,结果未定义。......
  • C++中promise和future初认识
    future/promisefuture提供了一个基于数据(future模板类型)的异步概念:对于一个类型T,可以在以后通过get接口获得这个类型T的变量。或者打个不太恰当的比方,当你获得一个future对象时,就获得了一个消费券(consumer):拿着这张券可以兑换(get)一个T类型的结果(如果数据未就绪的话会阻塞等......