• c++ 实现配置文件类


          以前做java项目的时候,需要一些配置参数,java提供了Properties 类 来操作,存储配置,挺方便的,现在既然在看c++,就想着用c++来实现这么一个类。

          要求:

         1.支持注释,单行,多行注释都行

         2.简单的key/value 模型

         3.获取,修改,清空,存储操作等

         接口头文件:properties.h

        

    #ifndef PROPERTIES_H
    #define PROPERTIES_H
    #include <string>
    #include <map>
    namespace huals{
    class Properties{
    private 
    //配置文件路径
    std::string filepath;
    //配置选项存储pair<key,value>
    std::map<std::string,std::string> pps;
    //注释存储pair<key,annotation>
    std::map<std::string,std::string> ann;
    public:
    Properties(std::string file);
    std::string Get_property(std::string key);
    void Set_property(std::string key,std::string value);
    int Save();
    void Clear();
    //测试用,输出配置文件的内容
    void Print();
    };
    }
    #include "properties.cpp"
    #endif

    具体实现:properties.cpp

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <map>
    #include <sstream>
    #include <cstring>
    namespace huals{
    //may throw error
    Properties::Properties(std::string file):filepath(file){
    std::fstream in;
    in.open(file.c_str());
    if(!in)
    return ;
    std::string line;
    //注释
    std::string annotation;
    while(getline(in,line)){
    std::string key;
    std::string value;
    /*
    *去掉字符串头尾空字符
    */
    int start,end;
    start=line.find_first_not_of(" ");
    end=line.find_last_not_of(" ");
    if(start<0)
    start=0;
    line=line.substr(start,end-start+1);
    //如果以#开头,则为配置文件
    if('#'==line[0]){
    annotation+=line+"
    ";
    }else{
    start=line.find_first_of("=");
    key=line.substr(0,start);
    value=line.substr(start+1,line.size()-start);
    pps.insert(make_pair(key,value));
    /*
    *注释是在配置的前面,如果注释不为空,则插入注释map
    */
    if(!annotation.empty()){
    ann.insert(make_pair(key,annotation));
    annotation.clear();
    }
    }
    }
    in.close();
    }
    //if the key not in map, return empty string
    std::string Properties::Get_property(std::string key){
    std::string value;
    std::map<std::string,std::string>::iterator it=pps.find(key);
    if(it!=pps.end())
    value=it->second;
    return value;
    }
    /*
    *设置配置项,key不存在,将会添加
    */
    void Properties::Set_property(std::string key,std::string value){
    pps[key]=value;
    }
    /*
    *存档,写入配置文件
    */
    int Properties::Save(){
    std::ofstream out;
    out.open(filepath.c_str(),std::ofstream::out);
    std::map<std::string,std::string>::iterator temp,it=pps.begin();
    while(it!=pps.end()){
    std::string line;
    temp=ann.find(it->first);
    if(temp!=ann.end())
    out<<temp->second;
    line+=it->first+"=";
    line+=it->second;
    out<<line<<std::endl;
    it++;
    }
    out.close();
    return 0;
    }
    /*
    *清空配置项,注意清空后调用Save()才有效
    */
    void Properties::Clear(){
    pps.clear();
    ann.clear();
    }
    //配置文件输出测试
    void Properties::Print(){
    std::map<std::string,std::string>::iterator temp,it=pps.begin();
    while(it!=pps.end()){
    std::string line;
    temp=ann.find(it->first);
    if(temp!=ann.end())
    std::cout<<temp->second;
    line+=it->first+"=";
    line+=it->second;
    std::cout<<line<<std::endl;
    it++;
    }
    }
    
    }

    经过测试,这个类基本满足要求。

    待改进:

    1.中文支持,没有特别设置编码这些信息,楼主在fedora 系统编码utf-8下测试是支持中文的

    2.异常处理,读写配置文件都可能发生异常,这个需要改进

    3.线程安全,如果有多个线程同时读写配置文件,需重写此类

    下面顺便写一个简单c++ 整数转成字符串东东,不用itoa这种偏c的东西

    #include <iostream>
    #include <sstream>
    #include <string>
    
    int main(void){
    ostringstream oss;
    int a=12;
    oss<<a;
    std::string str=oss.str();
    std::cout<<str<<std::endl;
    return 0;
    }

    over,好好学习,daydayup!

  • 相关阅读:
    c/c++ 数组的智能指针 使用
    c/c++ 智能指针 weak_ptr 使用
    在ubuntu18.04上安装EOS
    c/c++ 智能指针 unique_ptr 使用
    python基础-内置装饰器classmethod和staticmethod
    java中5种异步转同步方法
    java自定义注解
    多线程之线程池(Thread,Runnable,callable,Future,FutureTask)
    java反射
    重写ThreadFactory方法和拒绝策略
  • 原文地址:https://www.cnblogs.com/huals/p/3143265.html
Copyright © 2020-2023  润新知