我比较喜欢ini格式的配置文件,但是网上找到的直接可以用的ini读取类都是Windows API做的,也没办法,毕竟是windows环境下的一种日志格式,于是用一下午的时间仿照这种格式做了一个类似的日志读取类。
配置文件的格式类似这样:
[SwanQPeMicroserver1]
port=8080
IP=0.0.0.0
[SwanQPeMicroserver2]
port=8080
IP=0.0.0.0
[end]
具体的使用方法类型这样:
string ss(".\\配置文件.zy");
ConFigInTxt test(ss,"");
test.SetConfigInfo();
config_return_type temp_config_info_map;
temp_config_info_map = test.GetConfigInfo();
for (auto a : temp_config_info_map)
{
cout << a.first << endl;
for (auto b:a.second)
{
cout << b.first << " == " << b.second << endl;
}
}
其中,config_return_type是map<string,map<string,string>>类型的
运行结果如下:
这只是完成了一个从无到有的过程,具体接下来要做的事情还很多,比如为里面的值添加类型(int, float,string),允许添加注释等。。。
代码放在后面,如果您有什么想法、建议,可以指教,谢谢!
#pragma once
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
using config_return_type = map<string, map<string, string>> ;
class ConFigInTxt
{
public:
//************************************
// 创建日期: 2018/01/24
// 函数名称: ConFigInTxt
// 完整名称: ConFigInTxt::ConFigInTxt
// 功能描述: 初始化fstream 对象
// 返回描述: void
//************************************
ConFigInTxt();
//************************************
// 创建日期: 2018/01/24
// 函数名称: ConFigInTxt
// 完整名称: ConFigInTxt::ConFigInTxt
// 功能描述:
// 返回描述:
// 参数描述: std::string config_name
// 参数描述: std::string config_path
//************************************
ConFigInTxt(std::string config_name,std::string config_path );
//************************************
// 创建日期: 2018/01/24
// 函数名称: OpenConfig
// 完整名称: ConFigInTxt::OpenConfig
// 功能描述: 根据传入的配置文件名与路径打开配置文件
// 返回描述: bool
// 参数描述: std::string config_name
// 参数描述: std::string config_path
//************************************
bool OpenConfig(std::string config_name, std::string config_path );
//************************************
// 创建日期: 2018/01/24
// 函数名称: GetConfigInfo
// 完整名称: ConFigInTxt::GetConfigInfo
// 功能描述: 将配置文件中的信息传入到map中
// 返回描述: bool
//************************************
bool SetConfigInfo();
//************************************
// 创建日期: 2018/01/24
// 函数名称: GetConfigInfo
// 完整名称: ConFigInTxt::GetConfigInfo
// 功能描述: 将ConfigInfoMap返回
// 返回描述: std::map<std::string, std::map<std::string, std::string>>
//************************************
const std::map<std::string, std::map<std::string, std::string>> GetConfigInfo();
//************************************
// 创建日期: 2018/01/24
// 函数名称: ~ConFigInTxt
// 完整名称: ConFigInTxt::~ConFigInTxt
// 功能描述: 析构:释放资源
// 返回描述: void
//************************************
~ConFigInTxt();
private:
//std::map<std::string, std::string> item_info;
std::map<std::string, std::map<std::string, std::string>> config_info;
std::string config_name;
std::string config_path;
bool config_tag;
private:
bool ConfigToMap();
};
#include "config_read_txt.h"
using namespace std;
ConFigInTxt::ConFigInTxt()
{
//本函数中使用namespace std
using namespace std;
//默认构造的配置对象不可以直接使用操作方法
this->config_tag = false;
}
ConFigInTxt::ConFigInTxt(std::string config_name, std::string config_path)
{
//先判断config_name中是不是已经包含了路径
if (config_name.find("\\") != string::npos || config_name.find("/") != string::npos)
{
//然后判断config_path是不是为NULL
if (config_path.size()){
cout << "重复路径!" << endl;
return;
}
else{
clog << "[WARNING:] 配置文件名中输入了路径" << endl;
//将文件名中的path提取出来放置并初始化成员变量
string tmp_name = config_name.substr(config_name.find_last_of("\\") == string::npos ? config_name.find_last_of("/") : config_name.find_last_of("\\"));
string tmp_path = config_name.substr(0, (config_name.find_last_of("\\") == string::npos ? config_name.find_last_of("/") : config_name.find_last_of("\\")) - string::npos);
this->config_name = tmp_name;
this->config_path = tmp_path;
}
}
else
{
this->config_name = config_name;
this->config_path = config_path;
}
this->config_tag = true;
}
bool ConFigInTxt::OpenConfig(std::string config_name, std::string config_path)
{
//本函数中使用namespace std
using namespace std;
//先判断config_name中是不是已经包含了路径
if (config_name.find("\\") != string::npos || config_name.find("/") != string::npos)
{
//然后判断config_path是不是为NULL
if (config_path.size()) {
cout << "重复路径!" << endl;
return false;
}
else {
clog << "[WARNING:] 配置文件名中输入了路径" << endl;
//将文件名中的path提取出来放置并初始化成员变量
string tmp_name = config_name.substr(config_name.find_last_of("\\") == string::npos ? config_name.find_last_of("/") : config_name.find_last_of("\\"));
string tmp_path = config_name.substr(0, (config_name.find_last_of("\\") == string::npos ? config_name.find_last_of("/") : config_name.find_last_of("\\")) - string::npos);
this->config_name = tmp_name;
this->config_path = tmp_path;
}
}
else
{
this->config_name = config_name;
this->config_path = config_path;
}
return true;
}
bool ConFigInTxt::SetConfigInfo()
{
//本函数中使用namespace std
using namespace std;
if(!this->ConfigToMap())
cerr << "[ERROR:] 该配置文件不可用" << endl;
return true;
}
const std::map<std::string, std::map<std::string, std::string>> ConFigInTxt::GetConfigInfo()
{
return (this->config_info);
}
bool ConFigInTxt::ConfigToMap()
{
//本函数中使用namespace std
using namespace std;
//初始化ifstream
ifstream config_ifstream(this->config_path + "\\" + this->config_name);
//若文件打开失败报错并返回
if (!config_ifstream)
{
cerr << "[ERROR:] 配置文件打开失败!" << endl;
this->config_tag = false;
return false;
}
this->config_tag = true;
string s;
string flag_item ("=") ;
string flag_class_left("[");
string flag_class_right("]");
string temp_class ;
string temp_item_Key;
string temp_item_Value;
map<string, string> temp_map ;
while (getline(config_ifstream, s))
{
//提取class
if (s.find(flag_class_left) != string::npos)
{
//先将上一个itemMap插入
if((temp_map.size()!=0)&& (temp_class.size()!=0))
{
pair<string, map<string, string>> temp_pair(temp_class, temp_map);
this->config_info.insert(temp_pair);
//清空temp_map
temp_map.clear();
temp_class.clear();
}
temp_class = s.substr(1, s.find_first_of(flag_class_right)-1);
}
//提取后续键值
else if((s.find(flag_item)!=string::npos)&&(temp_class.size()!=0))
{
temp_item_Key = s.substr(0, s.find(flag_item));
temp_item_Value = s.substr(s.find(flag_item)+1);
pair<string, string> temp_pair(temp_item_Key, temp_item_Value);
temp_map.insert(temp_pair);
}
}
config_ifstream.close();
return true;
}
ConFigInTxt::~ConFigInTxt()
{
//本函数中使用namespace std
using namespace std;
clog << "[INFO:] 配置文件对象已析构" << endl;
}