背景:编程过程中经常会遇到读取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 *********************************/
- <pre name="code" class="cpp">#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</pre><br>
- <pre></pre>
- <pre name="code" class="cpp">/***************实现文件 inifile.cpp******************/
- <pre name="code" class="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***类型的函数集</pre><br>
- // 测试用代码
- <pre></pre>
- <pre name="code" class="cpp">#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;
- }</pre><br>
- <br>
- <br>
- <br>
- <br>
- <p></p>
- <map></map>
- <pre></pre>
- <pre></pre>
-
- </pre>