读取ini文件信息
ini文件说明
(1)ini是一种配置文件,主要由多个section以及每个section多个option组成
(2)要求多个section不能重复,每一个section中的option不能重复
(3)注释一般采用# 打头的方式
ini文件样例
# 这个就认为是一个section
[mysql]
# 下面的这四个个就是[mysql]这个section下的option
username = root
password=root
ip = 127.0.0.1
port = 3306
思路
(1)解析ini文件就相当于把ini文件中的内容转换为c++中的某种容器。
(2)分析得出unordered_map<string, unordered_map<string, string>>这样的结构比较适合,所以选用。
(3)其次就是解析过程中要考虑书写不规范的问题
总览
#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <unordered_map>
using namespace std;
typedef unordered_map<string, unordered_map<string, string>> INI_DATA_TYPE;
class ParseIni
{
private:
// 解析出的数据
INI_DATA_TYPE m_data;
// 格式设置:删除字符串两边的空格
string strip(const string& str);
public:
// 初始化
ParseIni(const string& path);
// 得到所有数据
INI_DATA_TYPE getItems();
// 获取某个section下的所有option
unordered_map<string, string> getSection(const string& section);
// 获取一个某个section下的option
string getOption(const string& section, const string& option);
};
格式设置:删除字符串两边的空格
string ParseIni::strip(const string& str)
{
int start = str.find_first_not_of(" \t");
int end = str.find_last_not_of(" \r");
if (start == string::npos || end == string::npos) {
return "";
}
return str.substr(start, end - start + 1);
}
初始化操作
我们在初始化操作时,就会把ini文件内容进行解析并存储
ParseIni::ParseIni(const string& path)
{
// 逐行解析ini文件内容
ifstream ifs(path);
if (ifs.is_open()) {
string section;
int lineNum = 0;
while (!ifs.eof()) {
string line;
getline(ifs, line);
line = strip(line);
++lineNum;
if (line.empty() || line.front() == '#') {
continue;
}
int index = line.find('=');
if (line.front() == '[' && line.back() == ']') {
section = line.substr(1, line.size() - 2);
m_data[section] = unordered_map<string, string>();
}
else if (index != string::npos) {
string key = strip(line.substr(0, index));
string value = strip(line.substr(index + 1));
m_data[section].insert(make_pair(key, value));
}
else {
ifs.close();
throw string("文件的第").append(to_string(lineNum)).append("行格式不正确");
}
}
ifs.close();
}
else {
throw string(path + "文件不存在");
}
}
获取ini文件的所有数据
INI_DATA_TYPE ParseIni::getItems()
{
return m_data;
}
获取某个section下的所有option
unordered_map<string, string> ParseIni::getSection(const string& section)
{
if (m_data.count(section) == 0) {
throw string("数据").append(section).append("不存在");
}
return m_data[section];
}
获取某个section下的一个option对应的值
string ParseIni::getOption(const string& section, const string& option)
{
if (m_data.count(section) == 0) {
throw string("数据").append(section).append("不存在");
}
if (m_data[section].count(option) == 0) {
throw string("数据").append(section).append("下面的").append(option).append("不存在");
}
return m_data[section][option];
}