ini文件是Initialization File的缩写,即初始化文件,通常存放的是一个程序的初始化信息,是Windows的系统配置文件所采用的存储格式,统管windows的各项配置。ini文件的后缀名不一定是.ini,也可以是.cfg、.conf或者是.tx*。
ini文件是技术人员经常用到的一种系统配置方法,如何读取和快速识别ini文件中的内容实现起来比较烦琐,而STL是一个很好的解决方法,省去了许多底层函数的编制。
ini文件格式示例如
主要有三种元素:section、key和value。key-value也叫键值对,位于等号左右两侧。左侧叫做key,即关键码;右侧叫做值,它们是成对出现的。section是由中括号“[ ]”标识的。一个 ini 文件是由多个section组成的,一个section是由多个key-value键值对组成的。我们的任务就是把ini文件中的信息以一定的方式保存在程序结构中,代码如下所示。
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
class MySection {
string section;
map<string, string>mapKey;
public:
MySection(string section) {
this->section = section;
}
bool AddKeyValue(string key, string value) {
pair<string, string>p(key, value);
mapKey.insert(p);
return true;
}
void Show(ostream& os) {
os << section << endl;
for_each(mapKey.begin(), mapKey.end(), [&os](pair<string, string> p) {
os << "\t" << p.first << "=" << p.second << endl;
});
}
};
class MySectionCollect {
map<string, MySection>mapSection;
public:
bool AddSection(string strSection) {
pair<string, MySection>p(strSection, MySection(strSection));
mapSection.insert(p);
return true;
}
MySection* GetSection(string strSection) {
map<string, MySection>::iterator it = mapSection.find(strSection);
return &((*it).second);
}
void Show(ostream& os) {
auto it = mapSection.begin();
while (it != mapSection.end()) {
((*it).second).Show(os);
it++;
}
}
};
class ReadIni {
string strPath;
MySectionCollect& collect;
public:
ReadIni(string strPath, MySectionCollect& collect):strPath(strPath),collect(collect){}
void Trim(string& s) {
if (s != "") { //find_first_not_of返回下标位置
s.erase(0, s.find_first_not_of(" ")); //删除左空格
if (s != "") {
s.erase(s.find_last_not_of(" ") + 1); //删除右空格
}
}
}
string GetSection(string strText) {
strText.erase(0, strText.find_first_not_of("["));
strText.erase(strText.find_last_not_of("]") + 1);
return strText;
}
void GetPair(string strText, string& key, string& value) {
int pos = strText.find("=");
key = strText.substr(0, pos);
value = strText.substr(pos + 1, strText.length() - pos - 1);
Trim(key);
Trim(value);
}
void Process() {
string strLine = "";
string strSection = "";
string strKey = "";
string strValue = "";
MySection* pSection = NULL;
ifstream in(strPath.c_str());
while (!in.eof()) {
getline(in, strLine);
Trim(strLine);
if (strLine == "")continue;
if (strLine.at(0) == '[') {
strSection = GetSection(strLine);
collect.AddSection(strSection);
pSection = collect.GetSection(strSection);//获取当前对象的key-value键值对
}
if (strLine.at(0) != '[') {
GetPair(strLine, strKey, strValue);
pSection->AddKeyValue(strKey, strValue);
}
}
in.close();
}
};
int main() {
string path = "d:\\data.ini";
MySectionCollect collect;
ReadIni ri(path, collect);
ri.Process();
collect.Show(cout);
return 0;
}
从语义上来说,一个section由多个key-value键值对组成,一个ini文件由多个section 组成。因此前者与基本类MySection 相对应,后者与 MySection集合类MySectionCollect相对应。而 ReadIni是读ini文件类,主要功能是根据ini配置文件填充MySectionCollect 对象。
可以看出用map进行查询既简洁,速度又较vector、 list容器快,因此在 MySection,MySectionCollect类中有两个主要的map成员变量,而不是 vector,list成员变量。
标签:value,string,STL,section,c++,strText,ini,key From: https://blog.51cto.com/u_16491666/9610680