[C++][工具分享]读写ini文件类

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 &param);
	//设置配置数据
	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 &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)
				{
					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 &param);
	//设置配置数据
	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 &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)
				{
					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("####");
				}
			}
		}
	}
}

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值