Ini 文件读写之C++

参考来源:https://blog.csdn.net/m_buddy/article/details/54097131

目录

Ini文件格式

源码

测试源码 

测试结果


Ini文件格式

Ini 文件读写之C++_第1张图片

源码

//IniFile.h
#ifndef INIFILE_H_
#define INIFILE_H_
#include "stdafx.h"
#include 
#include 
#include 
#include 
#include 
using std::string;
using std::vector;
using std::map;
using std::ifstream;
using std::ofstream;
using std::endl;
using std::cout;
using std::stringstream;

//ini节点
class CSection
{
public:
	CSection(const string& section, const string&  key, const string&  value);
	string m_section;
	string m_key;
	string m_value;
};

//ini 键 值 对
class CKeyValue
{
public:
	void AddKeyValue(const string&  key, const string&  value);
	map m_keyValue;
};

class CIniFile
{
public:
	CIniFile();
	~CIniFile();
	bool LoadFromIni(const string&  filename);
	vector::size_type SetValue(const string&  section, const string&  key, const string&  value);
	map::size_type GetSize();
	bool SaveToIni(const string&  path);
	string GetValue(const string&  section, const string&  key);
	void StrToInt(const string&  str, int& num);
	void StrToDouble(const string&  str, double& num);
	void strToChar(const string&  str, char& num);
	string FolderPath();

	//返回一个不含strOld
	string strReplaceAll(const string& strResource, const string& strOld, const string& strNew);

	//去首尾空格
	string& Trim(string& str);
	
private:
	map m_secKeyValue;
};
#endif
//IniFile.cpp
#include "stdafx.h"
#include 
#include "IniFile.h"


CSection::CSection(const string&  section, const string&  key, const string&  value)
{
	this->m_section = section;
	this->m_key = key;
	this->m_value = value;
}

void CKeyValue::AddKeyValue(const string&  key, const string&  value)
{
	m_keyValue.insert(std::pair(key, value));
}

CIniFile::CIniFile()
{

}

CIniFile::~CIniFile()
{
	m_secKeyValue.clear();
}


//去除字符串str左右空格
string& CIniFile::Trim(string& str)
{
	str.erase(0, str.find_first_not_of(" \t\n\r"));
	str.erase(str.find_last_not_of(" \t\n\r") + 1);
	return  str;
}



/*
	加载ini文件filename
	思路:
		1、按 class {section、key、value } 数据结构读取ini中所有节点、键值内容
		2、利用map的insert属性,去重复得到所有section
		3、重组读取的ini内容为下面结构
				section1
					key1 value1
					key2 value2
				section2
					key3 value3
					key4 value4
*/
bool CIniFile::LoadFromIni(const string&  filename)
{
	ifstream outFile(filename.c_str());
	if (!outFile.is_open())
		return false;
	
	string strSection = "", strKey="", strValue="", strLine = "";
	vector vecSection;
	string::size_type posLeft = string::npos;
	string::size_type posRight = string::npos;
	string::size_type posKeyValue = string::npos;
	while (!outFile.eof())
	{
		getline(outFile, strLine);
		
		//空行
		if (0 == strLine.length())
			continue;

		//ini注释,以#开头
		if (0==strLine.find("#"))
			continue;

		//读section节点
		posLeft = strLine.find("[");
		posRight = strLine.find("]");
		if (string::npos != posLeft && string::npos != posRight)
		{
			strSection = strLine.substr(posLeft + strlen("["), posRight - posLeft - strlen("["));
			strKey = "";
			strValue = "";
		}

		//读key、value
		posKeyValue = strLine.find("=");
		if (string::npos != posKeyValue)
		{
			strKey = strLine.substr(0, posKeyValue);
			strValue = strLine.substr(posKeyValue + strlen("="), strLine.length() - posKeyValue - strlen("="));
		}


		if (strSection.length()>0 && strKey.length()>0 && strValue.length()>0)
		{
			CSection sec(strSection, strKey, strValue);
			vecSection.push_back(sec);
		}
	}
	outFile.close();
	outFile.clear();//清空缓冲

	//利用map的insert属性,去重复拿出所有节点
	map temp;
	for (vector::iterator it = vecSection.begin(); it != vecSection.end(); it++)
	{
		temp.insert(std::pair(it->m_section, ""));
	}

	/*
		重组ini结构
			section1
				key1 value1
				key2 value2
			section2
				key3 value3
				key4 value4
	*/
	for (map::iterator sectionItor = temp.begin(); sectionItor != temp.end(); sectionItor++)
	{
		CKeyValue keyValue;
		for (vector::iterator vecItor = vecSection.begin(); vecItor != vecSection.end(); vecItor++)
		{
			if (vecItor->m_section == sectionItor->first)
			{
				keyValue.AddKeyValue(vecItor->m_key, vecItor->m_value);
			}
		}
		m_secKeyValue.insert(std::pair(sectionItor->first, keyValue));
	}

	return true;
}

string CIniFile::GetValue(const string&  section, const string&  key)
{
	map::iterator secKeyValueItor = m_secKeyValue.find(section);
	map::iterator keyValue = secKeyValueItor->second.m_keyValue.find(key);
	if (keyValue==secKeyValueItor->second.m_keyValue.end() || keyValue->second.empty())
		return "";
	else
		return keyValue->second;
}


vector::size_type CIniFile::SetValue(const string&  section, const string&  key, const string&  value)
{
	map::iterator secKeyValue = m_secKeyValue.find(section);
	if (m_secKeyValue.end() != secKeyValue)
		secKeyValue->second.m_keyValue[key] = value;
	else
	{
		CKeyValue keyValue;
		keyValue.AddKeyValue(key, value);
		m_secKeyValue.insert(std::pair(section, keyValue));
	}
	return m_secKeyValue.size();
}

bool CIniFile::SaveToIni(const string&  path)
{
	ofstream inFile(path.c_str());
	if (!inFile.is_open())
		return false;

	for (map::iterator secKeyValue = m_secKeyValue.begin(); secKeyValue != m_secKeyValue.end(); secKeyValue++)
	{
		inFile << "[" << secKeyValue->first << "]" << endl;
		for (map::iterator keyValue = secKeyValue->second.m_keyValue.begin(); keyValue != secKeyValue->second.m_keyValue.end(); keyValue++)
		{
			inFile << keyValue->first << "=" << keyValue->second << endl;
		}
	}
	inFile.close();
	inFile.clear();
	return true;
}

void CIniFile::StrToInt(const string&  str, int& num)
{
	stringstream stream;
	stream << str;
	stream >> num;
}

void CIniFile::StrToDouble(const string&  str, double& num)
{
	stringstream stream;
	stream << str;
	stream >> num;
}

void CIniFile::strToChar(const string&  str, char& num)
{
	stringstream stream;
	stream << str;
	stream >> num;
}

map::size_type CIniFile::GetSize()
{
	return m_secKeyValue.size();
}

string CIniFile::FolderPath()
{
	char strBuf[256] = { 0 };
	GetModuleFileNameA(NULL, strBuf, sizeof(strBuf));
	string strTemp = strBuf;
	if (strTemp.empty())
		return strTemp;

	strTemp = strReplaceAll(strTemp, "\\", "/");
	string::size_type pos = strTemp.rfind("/");
	if (string::npos != pos)
		strTemp = strTemp.substr(0, pos);
	else
		strTemp = "";

	return strTemp;
}

//返回一个不含strOld
string CIniFile::strReplaceAll(const string& strResource, const string& strOld, const string& strNew)
{
	string::size_type pos = 0;
	string strTemp = strResource;
	do
	{
		if ((pos = strTemp.find(strOld)) != string::npos)
		{
			strTemp.replace(pos, strOld.length(), strNew);
		}
	} while (pos != string::npos);
	return strTemp;
}

测试源码 

// Test.cpp 

#include "stdafx.h"
#include "IniFile.h"

#define  SERVERINI "/ServerIni.ini"

class CServerIni
{
public:
	struct Server
	{
		string m_serverIp;
		int m_serverPort;
		int m_serverTimeOut;
	};
	struct Database 
	{
		string m_dataIp;
		string m_dataUserName;
		string m_dataName;
		string m_dataPassWd;
	};
	Server m_server;
	Database m_database;
};

int _tmain(int argc, _TCHAR* argv[])
{
	CIniFile iniFile;
	string strIniPath = iniFile.FolderPath();
	strIniPath += SERVERINI;
	iniFile.LoadFromIni(strIniPath);
	if (0 == iniFile.GetSize())
		return 0;

	CServerIni serIni;
	serIni.m_server.m_serverIp = iniFile.GetValue("Server", "ServerIP");
	iniFile.StrToInt(iniFile.GetValue("Server", "Port"), serIni.m_server.m_serverPort);
	iniFile.StrToInt(iniFile.GetValue("Server", "Timeout"), serIni.m_server.m_serverTimeOut);
	serIni.m_database.m_dataIp = iniFile.GetValue("Database", "DBIP");
	serIni.m_database.m_dataName = iniFile.GetValue("Database", "DBName");
	serIni.m_database.m_dataUserName = iniFile.GetValue("Database", "UsrName");
	serIni.m_database.m_dataPassWd = iniFile.GetValue("Database", "UsrPassWd");
	return 0;
}

测试结果

Ini 文件读写之C++_第2张图片

你可能感兴趣的:(c家族,Ini文件读写,c++,c++,读写ini文件,c++实现ini文件的读写,c++读取ini文件,ini配置文件读写,c++)