代码主要是做练习用的,水平有限,路过的大神看到代码有哪里不好的请帮忙指出来,万分感谢。
#pragma once
#include <map>
#include <list>
#include <unordered_map>
#include <vector>
#include <string>
#include <fstream>
#include <algorithm>
struct ValueElement
{
std::string key = "";
std::string value = "";
std::string comment = "";
std::string rcomment = "";
};
struct SectionElement
{
std::string section = "";
std::string comment = "";
std::string rcomment = "";
std::vector<ValueElement*> childs;
std::unordered_map<std::string, ValueElement*> mapChilds;
~SectionElement()
{
for (auto e = childs.begin(); e != childs.end(); e++)
{
delete *e;
}
mapChilds.clear();
childs.clear();
}
};
class Setting
{
public:
Setting(const char* file) : msFile(file)
{
//readSettings();
}
~Setting()
{
save();
clearAll();
}
void clearAll()
{
for (auto e = mvecElements.begin(); e != mvecElements.end(); e++)
{
delete* e;
}
mvecElements.clear();
mmapElements.clear();
}
void removeGroup(const std::string&& group)
{
if (mmapElements.find(group) != mmapElements.end())
{
SectionElement* section = mmapElements[group];
for (auto ss = mvecElements.begin(); ss != mvecElements.end(); ss++)
{
if ((*ss)->section == group)
{
mvecElements.erase(ss);
mmapElements.erase(group);
delete section;
break;
}
}
}
}
bool contains(const std::string&& section, const std::string&& key)
{
if (mmapElements.find(section) != mmapElements.end() &&
mmapElements.at(section)->mapChilds.find(key) != mmapElements.at(section)->mapChilds.end())
{
return true;
}
return false;
}
std::string fileName() const
{
return msFile;
}
void setValue(const std::string&& s, const std::string&& k, const std::string&& v)
{
std::string section(s);
std::string key(k);
std::string value(v);
trim(section);
trim(key);
trim(value);
if (mmapElements.find(section) != mmapElements.end())
{
if (mmapElements[section]->mapChilds.find(key) != mmapElements[section]->mapChilds.end())
{
mmapElements[section]->mapChilds[key]->value = value;
}
else
{
ValueElement* op_elem = new ValueElement();
op_elem->key = key;
op_elem->value = value;
mmapElements[section]->childs.push_back(op_elem);
mmapElements[section]->mapChilds[key] = op_elem;
}
}
else
{
SectionElement* op_elem = new SectionElement();
op_elem->section = section;
op_elem->comment = "\n";
mvecElements.push_back(op_elem);
mmapElements[section] = op_elem;
ValueElement* op_child_elem = new ValueElement();
op_child_elem->key = key;
op_child_elem->value = value;
op_elem->childs.push_back(op_child_elem);
op_elem->mapChilds[key] = op_child_elem;
}
}
std::string value(const std::string&& section, const std::string&& key)
{
if (mmapElements.find(section) != mmapElements.end() &&
mmapElements[section]->mapChilds.find(key) != mmapElements[section]->mapChilds.end())
{
return mmapElements[section]->mapChilds[key]->value;
}
return std::string("");
}
void deleteKey(const std::string&& section, const std::string&& key)
{
if (mmapElements.find(section) != mmapElements.end() &&
mmapElements[section]->mapChilds.find(key) != mmapElements[section]->mapChilds.end())
{
ValueElement* child = mmapElements[section]->mapChilds[key];
SectionElement* sec = mmapElements[section];
for (auto ele = sec->childs.begin(); ele != sec->childs.end(); ele++)
{
if ((*ele)->key == key)
{
sec->childs.erase(ele);
sec->mapChilds.erase(key);
delete (*ele);
}
}
}
}
std::list<std::string> allKeys()
{
}
bool save()
{
return writeSettings();
}
bool load()
{
return readSettings();
}
std::string readStringValue(const std::string&& section, const std::string&& key)
{
return value(std::move(section), std::move(key));
}
int readIntValue(const std::string&& section, const std::string&& key)
{
std::string s = value(std::move(section), std::move(key));
return stoi(s);
}
float readfloatValue(const std::string&& section, const std::string&& key)
{
std::string s = value(std::move(section), std::move(key));
return stof(s);
}
double readDoubleValue(const std::string&& section, const std::string&& key)
{
std::string s = value(std::move(section), std::move(key));
return stod(s);
}
bool readBoolValue(const std::string&& section, const std::string&& key)
{
std::string s = value(std::move(section), std::move(key));
transform(s.begin(), s.end(), s.begin(), ::tolower);
return s == "true" ? true : false;
}
void setIntValue(const std::string&& section, std::string&& key, int value)
{
setValue(std::move(section), std::move(key), std::to_string(value));
}
void setFloatValue(const std::string&& section, std::string&& key, float value)
{
setValue(std::move(section), std::move(key), std::to_string(value));
}
void setDoubleValue(const std::string&& section, std::string&& key, double value)
{
setValue(std::move(section), std::move(key), std::to_string(value));
}
void setBoolValue(const std::string&& section, std::string&& key, bool value)
{
std::string s = value == true ? "true" : "false";
setValue(std::move(section), std::move(key), std::move(s));
}
private:
bool readSettings()
{
if (msFile.empty()) return false;
std::ifstream ifs;
ifs.open(msFile.c_str(), std::ios::in);
if (!ifs.is_open())
{
return false;
}
std::string line;
std::string s_comment = "";
ValueElement* op_element = NULL;
SectionElement* root_elem = NULL;
while (std::getline(ifs, line))
{
trim(line);
if (line == "" || line.at(0) == ';')
{
s_comment += line + "\n";
continue;
}
if (line.at(0) == '[')
{
std::string str_session = "";
std::string str_comment = "";
parseSession(line, str_session, str_comment);
root_elem = new SectionElement;
root_elem->comment = s_comment;
root_elem->rcomment = str_comment;
root_elem->section = str_session;
mvecElements.push_back(root_elem);
mmapElements[str_session] = root_elem;
s_comment = "";
continue;
}
{
std::string str_key = "";
std::string str_value = "";
std::string str_comment = "";
parseChild(line, str_key, str_value, str_comment);
op_element = new ValueElement;
op_element->key = str_key;
op_element->value = str_value;
op_element->rcomment = str_comment;
op_element->comment = s_comment;
s_comment = "";
if (root_elem == NULL)
{
//error
return false;
}
else
{
root_elem->childs.push_back(op_element);
root_elem->mapChilds[str_key] = op_element;
}
}
}
ifs.close();
return true;
}
void parseSession(std::string& line, std::string& section, std::string& comment)
{
int i_index = line.find_first_of(']');
if (i_index == -1)
{
return; //error
}
section = line.substr(1, i_index - 1);
comment = line.substr(i_index + 1);
trim(section);
trim(comment);
}
void parseChild(std::string& line, std::string& key, std::string& value, std::string& comment)
{
int i_index_comment = line.find_first_of(';');
int i_index_value = line.find_first_of('=');
if (i_index_comment != -1)
{
comment = line.substr(i_index_comment);
value = line.substr(i_index_value + 1, i_index_comment - 1 - i_index_value);
}
else
{
//comment = "";
value = line.substr(i_index_value + 1);
}
key = line.substr(0, i_index_value);
trim(key);
trim(value);
trim(comment);
}
bool writeSettings()
{
std::ofstream of;
of.open(msFile, std::ios::out);
if (!of.is_open())
{
return false;
}
for (SectionElement* elem : mvecElements)
{
of << elem->comment;
of << "[" << elem->section << "]" << elem->rcomment + "\n";
for (ValueElement* child : elem->childs)
{
of << child->comment;
of << child->key << "=" << child->value << child->rcomment + "\n";
}
}
of.close();
return true;
}
void trim(std::string& s)
{
if (s.empty())
{
return;
}
s.erase(0, s.find_first_not_of(' '));
s.erase(s.find_last_not_of(' ') + 1);
}
private:
std::vector<SectionElement*> mvecElements;
std::unordered_map<std::string, SectionElement*> mmapElements;
std::string msCurSection;
std::string msFile;
char* mBuff;
int miFileSize;
};
void test()
{
Setting s("Config.ini");
s.load();
s.setBoolValue(" sec1 ", "aa", false);
s.setDoubleValue(" sys1 ", "bb", 1.1);
//s.deleteKey("sec1", "bb");
//s.removeGroup("sys1");
s.save();
}