Ini文件读取类,采用C++ STL实现

背景:编程过程中经常会遇到读取Ini文件的场合,封装一个方便的类,能否避免重复编写,以后可复用。ini文件的格式很简单,并且不像xml之类的配置文件严谨。通常用于配置简单的键值对。
本类测试文件如下:<server.ini>

#what
[server1]
 ip= 192.168.1.1
port=8888
type=ai

#no
[server2]
ip=10.10.10.10
port=5002
type=move

#shit
[server3]
ip=127.0.0.1
port=9527
type=cache

/*********************头文件   inifile.h *********************************/
#ifndef _INI_FILE_
#define _INI_FILE_

#include <string>
#include <map>
#include <iostream>

using namespace std;

#define MAX_LINE_BUF_SIZE				80
#define MAX_SECTION_CONTEXT_BUF_SIZE	40
#define MAX_KEY_SIZE					40
#define MAX_VALUE_SIZE					40

class IniFile
{
	typedef std::map< string, string > MapKeyValue;
	typedef map< string, MapKeyValue > MapSection;

public:
	IniFile();
	~IniFile();

	bool Init(char* szFileName);
	void Save();
	bool SaveAs(char* szFileName);
	void ShowFileContext();

	string GetValue(const string& strKey);
	string GetValueFromSection(const string& strSection, const string& strKey);

	int GetInt(const string& strKey);
	float GetFloat(const string& strKey);

private:
	void DelInvalidSign(char* szOldLine, char* szNewLine);
	bool IsNoteLine(char* szLine);
	bool IsEmptyLine(char* szLine);
	bool IsNewSection(char* szLine);
	bool IsKeyValueLine(char* szLine);

	bool GetNewSectionContext(char* szLine, string& strNewSectionContext);
	bool GetKeyValue(char* szLine, string& strKey, string& strValue);

private:
	string m_strFileName;
	MapSection m_mapSection;
};

#endif


/***************实现文件  inifile.cpp******************/
#include "inifile.h"

IniFile::IniFile( )
{

}

IniFile::~IniFile()
{

}

bool IniFile::Init( char* szFileName )
{
	if (NULL == szFileName || strlen(szFileName) == 0)
	{
		return false;
	}

	m_strFileName = szFileName;

	FILE* pFile = fopen( szFileName, "rb" );
	if (NULL == pFile)
	{
		return false;
	}

	char szReadLineBuf[MAX_LINE_BUF_SIZE];
	char szLineBuf[MAX_LINE_BUF_SIZE];
	string strCurSection;
	string strKey;
	string strValue;
	while(NULL != fgets(szReadLineBuf, MAX_LINE_BUF_SIZE, pFile))
	{
		DelInvalidSign(szReadLineBuf, szLineBuf);

		if (IsNoteLine(szLineBuf) || IsEmptyLine(szLineBuf))
		{
			continue;
		}
		else if (IsNewSection(szLineBuf))
		{
			GetNewSectionContext(szLineBuf, strCurSection);
		}
		else if (IsKeyValueLine(szLineBuf))
		{
			GetKeyValue(szLineBuf, strKey, strValue);
			m_mapSection[strCurSection][strKey] = strValue;
		}
		else
		{
			continue;
		}
	}

	return true;
}

bool IniFile::IsNoteLine( char* szLine )
{
	return (szLine[0] == '#');
}

bool IniFile::IsEmptyLine( char* szLine )
{
	int nLineSize = strlen(szLine);

	if (nLineSize == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

bool IniFile::IsNewSection( char* szLine )
{
	return (strchr(szLine, '[') && strchr(szLine, ']'));
}

bool IniFile::IsKeyValueLine( char* szLine )
{
	return (NULL != strchr(szLine, '='));
}

bool IniFile::GetNewSectionContext( char* szLine, string& strNewSectionContext )
{
	char szSectionContextBuf[MAX_SECTION_CONTEXT_BUF_SIZE] = {0};
	strNewSectionContext.clear();

	char* pSectionContextBegin = strchr(szLine, '[');
	char* pSectionContextEnd = strchr(szLine, ']');
	int nSectionContextLen = pSectionContextEnd - pSectionContextBegin - 1;

	memcpy_s(szSectionContextBuf, MAX_SECTION_CONTEXT_BUF_SIZE, pSectionContextBegin + 1, nSectionContextLen);
	strNewSectionContext = szSectionContextBuf;

	return true;
}

bool IniFile::GetKeyValue( char* szLine, string& strKey, string& strValue )
{
	strKey.clear();
	strValue.clear();

	char* pEqualPos = strchr(szLine, '=');
	char szKeyBuf[MAX_KEY_SIZE] = {0};
	char szValueBuf[MAX_VALUE_SIZE] = {0};
	int nKeyLen = pEqualPos - szLine;
	int nValueLen = strlen(szLine) - nKeyLen - 1;

	memcpy_s(szKeyBuf, MAX_KEY_SIZE, szLine, nKeyLen);
	strKey = szKeyBuf;

	memcpy_s(szValueBuf, MAX_VALUE_SIZE, pEqualPos + 1, nValueLen);
	strValue = szValueBuf;
	
	return true;
}

void IniFile::Save()
{

}

bool IniFile::SaveAs( char* szFileName )
{
	if (NULL == szFileName || strlen(szFileName) == 0)
	{
		return false;
	}

	FILE* pFile = fopen(szFileName, "w");
	if (NULL == pFile)
	{
		return false;
	}

	// 写入文件内容
	MapSection::iterator itSection = m_mapSection.begin();
	for (; itSection != m_mapSection.end(); itSection++)
	{
		MapKeyValue& refKeyValueMap = itSection->second;

		fprintf(pFile, "[%s]\n", itSection->first.c_str());

		MapKeyValue::iterator itKV = refKeyValueMap.begin();
		for (; itKV != refKeyValueMap.end(); itKV++)
		{
			fprintf(pFile, "%s=%s\n", itKV->first.c_str(),  itKV->second.c_str());
		}

		fprintf(pFile, "\n");
	}

	return true;
}

void IniFile::ShowFileContext()
{
	MapSection::iterator itSection = m_mapSection.begin();
	for (; itSection != m_mapSection.end(); itSection++)
	{
		MapKeyValue& refKeyValueMap = itSection->second;
		cout << "==============================" << endl;
		cout << "Section:" << itSection->first << endl;

		MapKeyValue::iterator itKV = refKeyValueMap.begin();
		for (; itKV != refKeyValueMap.end(); itKV++)
		{
			cout << itKV->first << " = " << itKV->second << endl;
		}
		cout << "==============================" << endl;
		cout << endl;
	}
}

void IniFile::DelInvalidSign( char* szOldLine, char* szNewLine )
{
	int iOldLineLen;
	if (NULL == szOldLine || (iOldLineLen = strlen(szOldLine)) == 0)
	{
		return;
	}

	char tmpChar;
	int nNewLineIndex = 0;
	for (int i = 0; i < iOldLineLen; i++)
	{
		tmpChar = szOldLine[i];
		if (tmpChar == ' '
			|| tmpChar == '\t'
			|| tmpChar == '\r'
			|| tmpChar == '\n')
		{
			continue;
		}

		szNewLine[nNewLineIndex++] = tmpChar;
	}

	szNewLine[nNewLineIndex] = 0;
}

std::string IniFile::GetValue( const string& strKey )
{
	MapSection::iterator itSection = m_mapSection.begin();
	for (; itSection != m_mapSection.end(); itSection++)
	{
		MapKeyValue& refKeyValueMap = itSection->second;
		MapKeyValue::iterator itKV = refKeyValueMap.find(strKey);
		if (itKV != refKeyValueMap.end())
		{
			return itKV->second;
		}
	}

	return "";
}

std::string IniFile::GetValueFromSection( const string& strSection, const string& strKey )
{
	MapSection::iterator itSection = m_mapSection.find(strSection);
	if (itSection == m_mapSection.end())
	{
		return "";
	}

	MapKeyValue& refKeyValueMap = itSection->second;
	MapKeyValue::iterator itKV = refKeyValueMap.find(strKey);
	if (itKV != refKeyValueMap.end())
	{
		return itKV->second;
	}

	return "";
}

int IniFile::GetInt( const string& strKey )
{
	string str = GetValue(strKey);

	return atoi(str.c_str());
}

float IniFile::GetFloat( const string& strKey )
{
	string str = GetValue(strKey);

	return atof(str.c_str());
}

//因为配置文件中记录的数据均以字符串形式独处,可以根据需要获取的数据类型,自行定义Get***类型的函数集

// 测试用代码

#include "inifile.h"
#include <iostream>

using namespace std;

int main(int argc, char* argv[])
{

	IniFile file;

	if (!file.Init("server.ini"))
	{
		return -1;
	} 
	
	// 现实配置文件的全部内容
	file.ShowFileContext();

	cout << file.GetInt("port") << endl;
	cout << file.GetValueFromSection("server2","ip") << endl;
	

	// 将文件另存为
	//file.SaveAs("heihei.ini");

	return 0;
}







  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值