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!

原文地址:https://www.cnblogs.com/huals/p/3143265.html