IniFileOperate.h
//_CRT_SECURE_NO_WARNINGS
#pragma once
#include <string>
#include <vector>
typedef struct _nRoot
{
std::string name;//根节点的名字
int begin;//开始的行数
std::vector<std::string> member;//成员
std::vector<std::string> para;//成员
}nRoot;
class CIniFileOperate
{
public:
CIniFileOperate();
~CIniFileOperate();
//打开文件
bool OpenIniFile(std::string path);
//保存文件,无输入默认替换原文件
bool SaveIniFile(std::string path = "");
//得到配置数据
bool GetPara(std::string root,std::string name, std::string ¶m);
//设置配置数据
bool SetPara(std::string root, std::string name, std::string param);
protected:
//写入文件
bool WirteIniFile(std::string path, std::vector<nRoot> data);
//数据预处理,消除注释部分,只提供#和/注释
void PreAnalyse();
//数据处理,分组
void Analyse();
private:
std::string m_FilePath;//文件夹路径
std::vector<std::string> m_AllIniData;//所有的原始数据
std::vector<std::string> m_nData;//经过预处理之后的
std::vector<nRoot> m_nRoot;//有用的
};
//获取程序运行路径
std::string GetHomeFolder();
IniFileOperate.cpp
#include "stdafx.h"
#include "IniFileOperate.h"
#include <iostream>
#include <fstream>
#include <ostream>
#include <stdlib.h>
CIniFileOperate::CIniFileOperate()
{
#ifdef _DEBUG
std::cout << "本类暂时仅支持的注释如下:#,/" << std::endl;
#endif
}
CIniFileOperate::~CIniFileOperate()
{
}
std::string GetHomeFolder()
{
std::string path = _pgmptr;//_pgmptr仅在多字节字符中生效,Unicode会报错
size_t pos = path.rfind('\\');
path = path.substr(0, pos);
return path + "\\";
}
bool fileExist(std::string path)
{
std::ifstream fin(path);
if (!fin)
{
return false;
}
return true;
}
int GetKeyWordPos(char key,std::string LineWord)
{
char bKey;
int pos = -1;
size_t p = LineWord.find(key);
pos = static_cast<int>(p);
return pos;
}
bool CIniFileOperate::OpenIniFile(std::string path)
{
std::ifstream fin(path);
if (!fin)
{
//文件不存在
return false;
}
m_FilePath = path;
m_AllIniData.clear();
std::string line;
while (std::getline(fin, line))
{
m_AllIniData.push_back(line);
}
fin.close();
PreAnalyse();
Analyse();
return true;
}
bool CIniFileOperate::SaveIniFile(std::string path)
{
std::string newPath;
if (path == "")
{
newPath = m_FilePath;
}
else
{
newPath = path;
}
return WirteIniFile(newPath, m_nRoot);
}
bool CIniFileOperate::WirteIniFile(std::string path, std::vector<nRoot> data)
{
if (data.empty())return false;
int j = 0;
int n = 0;
std::ofstream fout(path);
if (fout.is_open())
{
for (int i = 0; i < m_AllIniData.size(); i++)
{
if (i < n)
{
continue;
}
if (j >= data.size())
{
//防止未知bug
fout.close();
return true;
}
if (i<data.at(j).begin || i>data.at(j).begin + data.at(j).member.size())
{
fout << m_AllIniData.at(i) << std::endl;
n++;
}
else
{
fout << m_AllIniData.at(i) << std::endl;
for (int k = 0; k < data.at(j).member.size(); k++)
{
if (GetKeyWordPos('#', data.at(j).member.at(k)) >= 0 || GetKeyWordPos('/', m_AllIniData.at(i)) == 0)
{
//有注释的情况下
fout << m_AllIniData.at(i+k+1) << std::endl;
}
else
{
fout << data.at(j).member.at(k) + "=" + data.at(j).para.at(k) << std::endl;
}
//统计一下当前到了多少行
n = i + k + 2;
}
j++;
}
}
fout.close();
return true;
}
fout.close();
return false;
}
bool CIniFileOperate::GetPara(std::string root, std::string name, std::string ¶m)
{
for (int i = 0; i < m_nRoot.size(); i++)
{
if (m_nRoot.at(i).name == root)
{
for (int j = 0; j < m_nRoot.at(i).member.size(); j++)
{
if (m_nRoot.at(i).member.at(j) == name)
{
param = m_nRoot.at(i).para.at(j);
return true;
}
}
}
}
return false;
}
bool CIniFileOperate::SetPara(std::string root, std::string name, std::string param)
{
for (int i = 0; i < m_nRoot.size(); i++)
{
if (m_nRoot.at(i).name == root)
{
for (int j = 0; j < m_nRoot.at(i).member.size(); j++)
{
if (m_nRoot.at(i).member.at(j) == name)
{
m_nRoot.at(i).para.at(j) = param;
return true;
}
}
}
}
return false;
}
void CIniFileOperate::PreAnalyse()
{
m_nData.clear();
for (int i = 0; i < m_AllIniData.size(); i++)
{
if (GetKeyWordPos('#', m_AllIniData.at(i)) >= 0 || GetKeyWordPos('/', m_AllIniData.at(i)) == 0)
{
m_nData.push_back("####");
continue;
}
m_nData.push_back(m_AllIniData.at(i));
}
}
void CIniFileOperate::Analyse()
{
m_nRoot.clear();
int j = 0;
for (int i = 0; i < m_nData.size(); i++)
{
//
if (i < j)
{
continue;
}
int p = GetKeyWordPos('[', m_nData.at(i));
if (p>= 0)
{
nRoot root;
root.begin = i;
int q = m_nData.at(i).rfind(']');
root.name = m_nData.at(i).substr(p + 1, q - p-1);
for (j = i+1; j < m_nData.size(); j++)
{
p = GetKeyWordPos('=', m_nData.at(j));
if (p > 0)
{
root.member.push_back(m_nData.at(j).substr(0, p));
root.para.push_back(m_nData.at(j).substr(p + 1, m_nData.at(j).length() - p));
if (j == m_nData.size() - 1)
{
//到最后一行
m_nRoot.push_back(root);
return;
}
}
else if (GetKeyWordPos('[', m_nData.at(j)) >= 0 )
{
m_nRoot.push_back(root);
break;
}
else
{
root.member.push_back("####");
root.para.push_back("####");
}
}
}
}
}
@2020.4.17,v1.1版本
1.增加节点及参数查找
2.增加插入配置
@2020.8.2, v1.2
1.修复当参数为中文时乱码问题
//_CRT_SECURE_NO_WARNINGS
#pragma once
#include <string>
#include <vector>
typedef struct _nRoot
{
std::string name;//根节点的名字
int begin;//开始的行数
std::vector<std::string> member;//成员
std::vector<std::string> para;//成员
}nRoot;
class CIniFileOperate
{
protected:
CIniFileOperate();
~CIniFileOperate();
public:
static CIniFileOperate *getIni();
std::string GetAppFilePath();
//打开文件
bool OpenIniFile(std::string path);
//保存文件,无输入默认替换原文件
bool SaveIniFile(std::string path = "");
//得到配置数据
bool GetPara(std::string root,std::string name, std::string ¶m);
//设置配置数据
bool SetPara(std::string root, std::string name, std::string param);
//检查是否存在根
bool CheckRootName(std::string root);
//检查是否存在参数名
bool CheckParamName(std::string root, std::string name);
//插入一个数据
bool InsertPara(std::string root, std::string name, std::string param);
protected:
//写入文件
bool WirteIniFile(std::string path, std::vector<nRoot> data);
//数据预处理,消除注释部分,只提供#和/注释
void PreAnalyse();
//数据处理,分组
void Analyse();
//取一组数据
int GetnRoot(std::string rootName,nRoot &root);
private:
std::string m_FilePath;//文件夹路径
std::vector<std::string> m_AllIniData;//所有的原始数据
std::vector<std::string> m_nData;//经过预处理之后的
std::vector<nRoot> m_nRoot;//有用的
};
//获取程序运行路径
std::string GetHomeFolder();
#include "stdafx.h"
#include "IniFileOperate.h"
#include <iostream>
#include <fstream>
#include <ostream>
#include <stdlib.h>
CIniFileOperate::CIniFileOperate()
{
#ifdef _DEBUG
std::cout << "本类暂时仅支持的注释如下:#,/" << std::endl;
#endif
}
CIniFileOperate::~CIniFileOperate()
{
}
#if 0
std::string CIniFileOperate::GetAppFilePath()
{
std::string szPath;
char szBuff[MAX_PATH] = { 0 };
HMODULE hModuleInstance = _AtlBaseModule.GetModuleInstance();
GetModuleFileNameA(hModuleInstance, szBuff, MAX_PATH);
szPath = szBuff;
szPath = szPath.substr(0, szPath.rfind('\\'));
return szPath+"\\";
}
#endif
std::string GetHomeFolder()
{
std::string path = _pgmptr;//_pgmptr仅在多字节字符中生效,Unicode会报错
size_t pos = path.rfind('\\');
path = path.substr(0, pos);
return path + "\\";
}
bool fileExist(std::string path)
{
std::ifstream fin(path);
if (!fin)
{
return false;
}
return true;
}
int GetKeyWordPos(char key,std::string LineWord)
{
char bKey;
int pos = -1;
size_t p = LineWord.find(key);
pos = static_cast<int>(p);
return pos;
}
CIniFileOperate *CIniFileOperate::getIni()
{
static CIniFileOperate ini;
return &ini;
}
std::string UTF8ToGB(const char* str)
{
std::string result;
WCHAR *strSrc;
LPSTR szRes;
//获得临时变量的大小
int i = MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0);
strSrc = new WCHAR[i + 1];
MultiByteToWideChar(CP_UTF8, 0, str, -1, strSrc, i);
//获得临时变量的大小
i = WideCharToMultiByte(CP_ACP, 0, strSrc, -1, NULL, 0, NULL, NULL);
szRes = new CHAR[i + 1];
WideCharToMultiByte(CP_ACP, 0, strSrc, -1, szRes, i, NULL, NULL);
result = szRes;
delete[]strSrc;
delete[]szRes;
return result;
}
bool CIniFileOperate::OpenIniFile(std::string path)
{
std::ifstream fin(path);
if (!fin)
{
//文件不存在
return false;
}
m_FilePath = path;
m_AllIniData.clear();
std::string line;
while (std::getline(fin, line))
{
std::string str = UTF8ToGB(line.c_str()).c_str();
m_AllIniData.push_back(str);
}
fin.close();
PreAnalyse();
Analyse();
return true;
}
bool CIniFileOperate::SaveIniFile(std::string path)
{
std::string newPath;
if (path == "")
{
newPath = m_FilePath;
}
else
{
newPath = path;
}
return WirteIniFile(newPath, m_nRoot);
}
bool CIniFileOperate::WirteIniFile(std::string path, std::vector<nRoot> data)
{
if (data.empty())return false;
int j = 0;
int n = 0;
std::ofstream fout(path);
if (fout.is_open())
{
for (int i = 0; i < m_AllIniData.size(); i++)
{
if (i < n)
{
continue;
}
if (j >= data.size())
{
//防止未知bug
fout.close();
return true;
}
if (i<data.at(j).begin || i>data.at(j).begin + data.at(j).member.size())
{
fout << m_AllIniData.at(i) << std::endl;
n++;
}
else
{
fout << m_AllIniData.at(i) << std::endl;
for (int k = 0; k < data.at(j).member.size(); k++)
{
if (GetKeyWordPos('#', data.at(j).member.at(k)) >= 0 || GetKeyWordPos('/', m_AllIniData.at(i)) == 0)
{
//有注释的情况下
fout << m_AllIniData.at(i+k+1) << std::endl;
}
else
{
fout << data.at(j).member.at(k) + "=" + data.at(j).para.at(k) << std::endl;
}
//统计一下当前到了多少行
n = i + k + 2;
}
j++;
}
}
fout.close();
return true;
}
fout.close();
return false;
}
int CIniFileOperate::GetnRoot(std::string rootName, nRoot &root)
{
for (int i = 0; i < m_nRoot.size(); i++)
{
if (strcmp(rootName.c_str(), m_nRoot[i].name.c_str()) == 0)
{
root = m_nRoot[i];
return i;
}
}
return -1;
}
bool CIniFileOperate::CheckRootName(std::string root)
{
nRoot nRootParam;
if (GetnRoot(root, nRootParam) < 0)
{
return false;
}
return true;
}
bool CIniFileOperate::CheckParamName(std::string root, std::string name)
{
nRoot nRootParam;
if (GetnRoot(root, nRootParam)>=0)
{
for (int j = 0; j < nRootParam.member.size(); j++)
{
if (strcmp(name.c_str(), nRootParam.member[j].c_str()) == 0)
{
return true;
}
}
}
return false;
}
bool CIniFileOperate::InsertPara(std::string root, std::string name, std::string param)
{
nRoot nRootParam;
int re = GetnRoot(root, nRootParam);
if (re<0)
{
std::string data;
data = "[" + root+"]";
m_AllIniData.push_back(data);
nRootParam.name = root;
nRootParam.begin = m_AllIniData.size()-1;
nRootParam.member.push_back(name);
nRootParam.para.push_back(param);
m_nRoot.push_back(nRootParam);
data = name + "=" + param;
m_AllIniData.push_back(data);
}
else
{
m_nRoot[re].member.push_back(name);
m_nRoot[re].para.push_back(param);
std::string data;
data = name + "=" + param;
if (m_nRoot[re].begin + m_nRoot[re].member.size()>m_AllIniData.size()-1)
{
//到最后一行了
m_AllIniData.push_back(data);
}
else
{
std::vector <std::string>::iterator theIterator = m_AllIniData.begin() + m_nRoot[re].begin + m_nRoot[re].member.size();
m_AllIniData.insert(theIterator, 1, data);
}
for (int i = re+1; i < m_nRoot.size();i++)
{
m_nRoot[i].begin +=1;
}
}
SaveIniFile();
return true;
}
bool CIniFileOperate::GetPara(std::string root, std::string name, std::string ¶m)
{
for (int i = 0; i < m_nRoot.size(); i++)
{
if (m_nRoot.at(i).name == root)
{
for (int j = 0; j < m_nRoot.at(i).member.size(); j++)
{
if (m_nRoot.at(i).member.at(j) == name)
{
param = m_nRoot.at(i).para.at(j);
return true;
}
}
}
}
return false;
}
bool CIniFileOperate::SetPara(std::string root, std::string name, std::string param)
{
for (int i = 0; i < m_nRoot.size(); i++)
{
if (m_nRoot.at(i).name == root)
{
for (int j = 0; j < m_nRoot.at(i).member.size(); j++)
{
if (m_nRoot.at(i).member.at(j) == name)
{
m_nRoot.at(i).para.at(j) = param;
SaveIniFile();
return true;
}
}
}
}
return false;
}
void CIniFileOperate::PreAnalyse()
{
m_nData.clear();
for (int i = 0; i < m_AllIniData.size(); i++)
{
if (GetKeyWordPos('#', m_AllIniData.at(i)) >= 0 || GetKeyWordPos('/', m_AllIniData.at(i)) == 0)
{
m_nData.push_back("####");
continue;
}
m_nData.push_back(m_AllIniData.at(i));
}
}
void CIniFileOperate::Analyse()
{
m_nRoot.clear();
int j = 0;
for (int i = 0; i < m_nData.size(); i++)
{
//
if (i < j)
{
continue;
}
int p = GetKeyWordPos('[', m_nData.at(i));
if (p>= 0)
{
nRoot root;
root.begin = i;
int q = m_nData.at(i).rfind(']');
root.name = m_nData.at(i).substr(p + 1, q - p-1);
for (j = i+1; j < m_nData.size(); j++)
{
p = GetKeyWordPos('=', m_nData.at(j));
if (p > 0)
{
root.member.push_back(m_nData.at(j).substr(0, p));
root.para.push_back(m_nData.at(j).substr(p + 1, m_nData.at(j).length() - p));
if (j == m_nData.size() - 1)
{
//到最后一行
m_nRoot.push_back(root);
return;
}
}
else if (GetKeyWordPos('[', m_nData.at(j)) >= 0 )
{
m_nRoot.push_back(root);
break;
}
else
{
root.member.push_back("####");
root.para.push_back("####");
}
}
}
}
}