在开源中国上找到的,原地址http://www.oschina.net/code/snippet_553781_37613。
原简介:
所做修改:
1.修复了读取时,不同段下会出现键值对重复的bug。
2.取消了空格消除。
3.不采用map格式输出,保证输出顺序即为写入顺序。
INIParser.h
#ifndef INI_PARSER_H
#define INI_PARSER_H
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <cstdlib>
#include <map>
using namespace std;
typedef std::pair<string,string> MyTypeSub;
typedef std::vector<MyTypeSub> MyVectorSub;
class ININode
{
public:
ININode(string root, string key, string value)
{
this->root = root;
this->key = key;
this->value = value;
}
string root;
string key;
string value;
};
class SubNode
{
public:
void InsertElement(string key, string value)
{
sub_node.insert(pair<string, string>(key, value));
}
std::map<string, string> sub_node;
MyVectorSub sub_nodevector;//key名加值
};
class INIParser
{
public:
int ReadINI(string path);
string GetValue(string root, string key);
vector<ININode>::size_type GetSize(){return map_ini.size();}
vector<ININode>::size_type SetValue(string root, string key, string value);
int WriteINI(string path);
void Clear(){map_ini.clear();}
private:
map<string, SubNode> map_ini;//段名加对象 用于检索
typedef pair<string, SubNode> MyType;
typedef vector<MyType> MyVector;
MyVector vector_ini; //用于输出
};
#endif // INI_PARSER_H
INIParser.cpp
#include "INIParser.h"
//remove all blank space
string & TrimString(string &str)
{
string::size_type pos = 0;
while(str.npos != (pos = str.find(" ")))
str = str.replace(pos, pos+1, "");
return str;
}
//read in INI file and parse it
int INIParser::ReadINI(string path)
{
ifstream in_conf_file(path.c_str());
if(!in_conf_file) return 0;
string str_line = "";
string str_root = "";
vector<ININode> vec_ini;
while(getline(in_conf_file, str_line))
{
string::size_type left_pos = 0;
string::size_type right_pos = 0;
string::size_type equal_div_pos = 0;
string str_key = "";
string str_value = "";
if((str_line.npos != (left_pos = str_line.find("["))) && (str_line.npos != (right_pos = str_line.find("]"))))
{
//cout << str_line.substr(left_pos+1, right_pos-1) << endl;
str_root = str_line.substr(left_pos+1, right_pos-1);
}
if(str_line.npos != (equal_div_pos = str_line.find("=")))
{
str_key = str_line.substr(0, equal_div_pos);
str_value = str_line.substr(equal_div_pos+1, str_line.size()-1);
//str_key = TrimString(str_key);
//str_value = TrimString(str_value);
//cout << str_key << "=" << str_value << endl;
}
if((!str_root.empty()) && (!str_key.empty()) )
{
ININode ini_node(str_root, str_key, str_value);
vec_ini.push_back(ini_node);
//cout << vec_ini.size() << endl;
}
}
in_conf_file.close();
in_conf_file.clear();
//vector convert to map
map<string, string> map_tmp;
for(vector<ININode>::iterator itr = vec_ini.begin(); itr != vec_ini.end(); ++itr)
{
map_tmp.insert(pair<string, string>(itr->root, ""));
}
SubNode sn;
for(map<string, string>::iterator itr1 = map_tmp.begin(); itr1 != map_tmp.end(); ++itr1)
{
//cout << itr->first << endl;
sn.sub_node.clear();
for(vector<ININode>::iterator sub_itr = vec_ini.begin(); sub_itr != vec_ini.end(); ++sub_itr)
{
if(sub_itr->root == itr1->first)
{
//cout << sub_itr->key << "=" << sub_itr->value << endl;
sn.InsertElement(sub_itr->key, sub_itr->value);
}
}
map_ini.insert(pair<string, SubNode>(itr1->first, sn));
}
for(vector<ININode>::iterator sub_itr2 = vec_ini.begin(); sub_itr2 != vec_ini.end(); ++sub_itr2)
{
SubNode sn2;
sn2.sub_nodevector.push_back(pair<string, string>(sub_itr2->key, sub_itr2->value));
bool bRootExist=false;
for (MyVector::iterator iter2=vector_ini.begin();iter2!=vector_ini.end();++iter2)
{
if (iter2->first==sub_itr2->root)
{
iter2->second.sub_nodevector.push_back(pair<string, string>(sub_itr2->key, sub_itr2->value));
bRootExist=true;
break;
}
}
if (!bRootExist)
{
vector_ini.push_back(pair<string, SubNode>(sub_itr2->root, sn2));
}
}
return 1;
}
//get value by root and key
string INIParser::GetValue(string root, string key)
{
map<string, SubNode>::iterator itr = map_ini.find(root);
map<string, string>::iterator sub_itr = itr->second.sub_node.find(key);
SubNode& ojb=itr->second;
string aa=sub_itr->first;
string bb=sub_itr->second;
if(!(sub_itr->second).empty())
return sub_itr->second;
return "";
}
//write ini file
int INIParser::WriteINI(string path)
{
ofstream out_conf_file(path.c_str());
if(!out_conf_file)
return -1;
// for(map<string, SubNode>::iterator itr = map_ini.begin(); itr != map_ini.end(); ++itr)
// {
// out_conf_file << "[" << itr->first << "]" << endl;
// for(map<string, string>::iterator sub_itr = itr->second.sub_node.begin(); sub_itr != itr->second.sub_node.end(); ++sub_itr)
// {
// out_conf_file << sub_itr->first << "=" << sub_itr->second << endl;
// }
// }
for (MyVector::iterator itervector=vector_ini.begin();itervector!=vector_ini.end();++itervector)
{
out_conf_file << "[" << itervector->first << "]" << endl;
for (MyVectorSub::iterator itersub=itervector->second.sub_nodevector.begin();itersub!=itervector->second.sub_nodevector.end();++itersub)
{
out_conf_file << itersub->first << "=" << itersub->second << endl;
}
}
out_conf_file.close();
out_conf_file.clear();
return 1;
}
//set value
vector<ININode>::size_type INIParser::SetValue(string root, string key, string value)
{
map<string, SubNode>::iterator itr = map_ini.find(root);
if(map_ini.end() != itr)
itr->second.sub_node.insert(pair<string, string>(key, value));
else
{
SubNode sn;
sn.InsertElement(key, value);
map_ini.insert(pair<string, SubNode>(root, sn));
}
//查找向量里是否有
bool find=false;
for (MyVector::iterator itervector=vector_ini.begin();itervector!=vector_ini.end();++itervector)
{
if(itervector->first==root)
{
itervector->second.sub_nodevector.push_back(pair<string, string>(key, value));
find=true;
break;
}
}
if (!find)
{
SubNode sn;
sn.sub_nodevector.push_back(pair<string, string>(key, value));
vector_ini.push_back(pair<string, SubNode>(root, sn));
}
return map_ini.size();
}