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

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

[plain]  view plain copy
  1. #what  
  2. [server1]  
  3.  ip= 192.168.1.1  
  4. port=8888  
  5. type=ai  
  6.   
  7. #no  
  8. [server2]  
  9. ip=10.10.10.10  
  10. port=5002  
  11. type=move  
  12.   
  13. #shit  
  14. [server3]  
  15. ip=127.0.0.1  
  16. port=9527  
  17. type=cache  

[cpp]  view plain copy
  1. /*********************头文件   inifile.h *********************************/  
  2. <pre name="code" class="cpp">#ifndef _INI_FILE_  
  3. #define _INI_FILE_  
  4.   
  5. #include <string>  
  6. #include <map>  
  7. #include <iostream>  
  8.   
  9. using namespace std;  
  10.   
  11. #define MAX_LINE_BUF_SIZE               80  
  12. #define MAX_SECTION_CONTEXT_BUF_SIZE    40  
  13. #define MAX_KEY_SIZE                    40  
  14. #define MAX_VALUE_SIZE                  40  
  15.   
  16. class IniFile  
  17. {  
  18.     typedef std::map< string, string > MapKeyValue;  
  19.     typedef map< string, MapKeyValue > MapSection;  
  20.   
  21. public:  
  22.     IniFile();  
  23.     ~IniFile();  
  24.   
  25.     bool Init(char* szFileName);  
  26.     void Save();  
  27.     bool SaveAs(char* szFileName);  
  28.     void ShowFileContext();  
  29.   
  30.     string GetValue(const string& strKey);  
  31.     string GetValueFromSection(const string& strSection, const string& strKey);  
  32.   
  33.     int GetInt(const string& strKey);  
  34.     float GetFloat(const string& strKey);  
  35.   
  36. private:  
  37.     void DelInvalidSign(char* szOldLine, char* szNewLine);  
  38.     bool IsNoteLine(char* szLine);  
  39.     bool IsEmptyLine(char* szLine);  
  40.     bool IsNewSection(char* szLine);  
  41.     bool IsKeyValueLine(char* szLine);  
  42.   
  43.     bool GetNewSectionContext(char* szLine, string& strNewSectionContext);  
  44.     bool GetKeyValue(char* szLine, string& strKey, string& strValue);  
  45.   
  46. private:  
  47.     string m_strFileName;  
  48.     MapSection m_mapSection;  
  49. };  
  50.   
  51. #endif</pre><br>  
  52. <pre></pre>  
  53. <pre name="code" class="cpp">/***************实现文件  inifile.cpp******************/  
  54. <pre name="code" class="cpp">#include "inifile.h"  
  55.   
  56. IniFile::IniFile( )  
  57. {  
  58.   
  59. }  
  60.   
  61. IniFile::~IniFile()  
  62. {  
  63.   
  64. }  
  65.   
  66. bool IniFile::Init( char* szFileName )  
  67. {  
  68.     if (NULL == szFileName || strlen(szFileName) == 0)  
  69.     {  
  70.         return false;  
  71.     }  
  72.   
  73.     m_strFileName = szFileName;  
  74.   
  75.     FILE* pFile = fopen( szFileName, "rb" );  
  76.     if (NULL == pFile)  
  77.     {  
  78.         return false;  
  79.     }  
  80.   
  81.     char szReadLineBuf[MAX_LINE_BUF_SIZE];  
  82.     char szLineBuf[MAX_LINE_BUF_SIZE];  
  83.     string strCurSection;  
  84.     string strKey;  
  85.     string strValue;  
  86.     while(NULL != fgets(szReadLineBuf, MAX_LINE_BUF_SIZE, pFile))  
  87.     {  
  88.         DelInvalidSign(szReadLineBuf, szLineBuf);  
  89.   
  90.         if (IsNoteLine(szLineBuf) || IsEmptyLine(szLineBuf))  
  91.         {  
  92.             continue;  
  93.         }  
  94.         else if (IsNewSection(szLineBuf))  
  95.         {  
  96.             GetNewSectionContext(szLineBuf, strCurSection);  
  97.         }  
  98.         else if (IsKeyValueLine(szLineBuf))  
  99.         {  
  100.             GetKeyValue(szLineBuf, strKey, strValue);  
  101.             m_mapSection[strCurSection][strKey] = strValue;  
  102.         }  
  103.         else  
  104.         {  
  105.             continue;  
  106.         }  
  107.     }  
  108.   
  109.     return true;  
  110. }  
  111.   
  112. bool IniFile::IsNoteLine( char* szLine )  
  113. {  
  114.     return (szLine[0] == '#');  
  115. }  
  116.   
  117. bool IniFile::IsEmptyLine( char* szLine )  
  118. {  
  119.     int nLineSize = strlen(szLine);  
  120.   
  121.     if (nLineSize == 0)  
  122.     {  
  123.         return true;  
  124.     }  
  125.     else  
  126.     {  
  127.         return false;  
  128.     }  
  129. }  
  130.   
  131. bool IniFile::IsNewSection( char* szLine )  
  132. {  
  133.     return (strchr(szLine, '[') && strchr(szLine, ']'));  
  134. }  
  135.   
  136. bool IniFile::IsKeyValueLine( char* szLine )  
  137. {  
  138.     return (NULL != strchr(szLine, '='));  
  139. }  
  140.   
  141. bool IniFile::GetNewSectionContext( char* szLine, string& strNewSectionContext )  
  142. {  
  143.     char szSectionContextBuf[MAX_SECTION_CONTEXT_BUF_SIZE] = {0};  
  144.     strNewSectionContext.clear();  
  145.   
  146.     char* pSectionContextBegin = strchr(szLine, '[');  
  147.     char* pSectionContextEnd = strchr(szLine, ']');  
  148.     int nSectionContextLen = pSectionContextEnd - pSectionContextBegin - 1;  
  149.   
  150.     memcpy_s(szSectionContextBuf, MAX_SECTION_CONTEXT_BUF_SIZE, pSectionContextBegin + 1, nSectionContextLen);  
  151.     strNewSectionContext = szSectionContextBuf;  
  152.   
  153.     return true;  
  154. }  
  155.   
  156. bool IniFile::GetKeyValue( char* szLine, string& strKey, string& strValue )  
  157. {  
  158.     strKey.clear();  
  159.     strValue.clear();  
  160.   
  161.     char* pEqualPos = strchr(szLine, '=');  
  162.     char szKeyBuf[MAX_KEY_SIZE] = {0};  
  163.     char szValueBuf[MAX_VALUE_SIZE] = {0};  
  164.     int nKeyLen = pEqualPos - szLine;  
  165.     int nValueLen = strlen(szLine) - nKeyLen - 1;  
  166.   
  167.     memcpy_s(szKeyBuf, MAX_KEY_SIZE, szLine, nKeyLen);  
  168.     strKey = szKeyBuf;  
  169.   
  170.     memcpy_s(szValueBuf, MAX_VALUE_SIZE, pEqualPos + 1, nValueLen);  
  171.     strValue = szValueBuf;  
  172.       
  173.     return true;  
  174. }  
  175.   
  176. void IniFile::Save()  
  177. {  
  178.   
  179. }  
  180.   
  181. bool IniFile::SaveAs( char* szFileName )  
  182. {  
  183.     if (NULL == szFileName || strlen(szFileName) == 0)  
  184.     {  
  185.         return false;  
  186.     }  
  187.   
  188.     FILE* pFile = fopen(szFileName, "w");  
  189.     if (NULL == pFile)  
  190.     {  
  191.         return false;  
  192.     }  
  193.   
  194.     // 写入文件内容  
  195.     MapSection::iterator itSection = m_mapSection.begin();  
  196.     for (; itSection != m_mapSection.end(); itSection++)  
  197.     {  
  198.         MapKeyValue& refKeyValueMap = itSection->second;  
  199.   
  200.         fprintf(pFile, "[%s]\n", itSection->first.c_str());  
  201.   
  202.         MapKeyValue::iterator itKV = refKeyValueMap.begin();  
  203.         for (; itKV != refKeyValueMap.end(); itKV++)  
  204.         {  
  205.             fprintf(pFile, "%s=%s\n", itKV->first.c_str(),  itKV->second.c_str());  
  206.         }  
  207.   
  208.         fprintf(pFile, "\n");  
  209.     }  
  210.   
  211.     return true;  
  212. }  
  213.   
  214. void IniFile::ShowFileContext()  
  215. {  
  216.     MapSection::iterator itSection = m_mapSection.begin();  
  217.     for (; itSection != m_mapSection.end(); itSection++)  
  218.     {  
  219.         MapKeyValue& refKeyValueMap = itSection->second;  
  220.         cout << "==============================" << endl;  
  221.         cout << "Section:" << itSection->first << endl;  
  222.   
  223.         MapKeyValue::iterator itKV = refKeyValueMap.begin();  
  224.         for (; itKV != refKeyValueMap.end(); itKV++)  
  225.         {  
  226.             cout << itKV->first << " = " << itKV->second << endl;  
  227.         }  
  228.         cout << "==============================" << endl;  
  229.         cout << endl;  
  230.     }  
  231. }  
  232.   
  233. void IniFile::DelInvalidSign( char* szOldLine, char* szNewLine )  
  234. {  
  235.     int iOldLineLen;  
  236.     if (NULL == szOldLine || (iOldLineLen = strlen(szOldLine)) == 0)  
  237.     {  
  238.         return;  
  239.     }  
  240.   
  241.     char tmpChar;  
  242.     int nNewLineIndex = 0;  
  243.     for (int i = 0; i < iOldLineLen; i++)  
  244.     {  
  245.         tmpChar = szOldLine[i];  
  246.         if (tmpChar == ' '  
  247.             || tmpChar == '\t'  
  248.             || tmpChar == '\r'  
  249.             || tmpChar == '\n')  
  250.         {  
  251.             continue;  
  252.         }  
  253.   
  254.         szNewLine[nNewLineIndex++] = tmpChar;  
  255.     }  
  256.   
  257.     szNewLine[nNewLineIndex] = 0;  
  258. }  
  259.   
  260. std::string IniFile::GetValue( const string& strKey )  
  261. {  
  262.     MapSection::iterator itSection = m_mapSection.begin();  
  263.     for (; itSection != m_mapSection.end(); itSection++)  
  264.     {  
  265.         MapKeyValue& refKeyValueMap = itSection->second;  
  266.         MapKeyValue::iterator itKV = refKeyValueMap.find(strKey);  
  267.         if (itKV != refKeyValueMap.end())  
  268.         {  
  269.             return itKV->second;  
  270.         }  
  271.     }  
  272.   
  273.     return "";  
  274. }  
  275.   
  276. std::string IniFile::GetValueFromSection( const string& strSection, const string& strKey )  
  277. {  
  278.     MapSection::iterator itSection = m_mapSection.find(strSection);  
  279.     if (itSection == m_mapSection.end())  
  280.     {  
  281.         return "";  
  282.     }  
  283.   
  284.     MapKeyValue& refKeyValueMap = itSection->second;  
  285.     MapKeyValue::iterator itKV = refKeyValueMap.find(strKey);  
  286.     if (itKV != refKeyValueMap.end())  
  287.     {  
  288.         return itKV->second;  
  289.     }  
  290.   
  291.     return "";  
  292. }  
  293.   
  294. int IniFile::GetInt( const string& strKey )  
  295. {  
  296.     string str = GetValue(strKey);  
  297.   
  298.     return atoi(str.c_str());  
  299. }  
  300.   
  301. float IniFile::GetFloat( const string& strKey )  
  302. {  
  303.     string str = GetValue(strKey);  
  304.   
  305.     return atof(str.c_str());  
  306. }  
  307.   
  308. //因为配置文件中记录的数据均以字符串形式独处,可以根据需要获取的数据类型,自行定义Get***类型的函数集</pre><br>  
  309. // 测试用代码  
  310. <pre></pre>  
  311. <pre name="code" class="cpp">#include "inifile.h"  
  312. #include <iostream>  
  313.   
  314. using namespace std;  
  315.   
  316. int main(int argc, char* argv[])  
  317. {  
  318.   
  319.     IniFile file;  
  320.   
  321.     if (!file.Init("server.ini"))  
  322.     {  
  323.         return -1;  
  324.     }   
  325.       
  326.     // 现实配置文件的全部内容  
  327.     file.ShowFileContext();  
  328.   
  329.     cout << file.GetInt("port") << endl;  
  330.     cout << file.GetValueFromSection("server2","ip") << endl;  
  331.       
  332.   
  333.     // 将文件另存为  
  334.     //file.SaveAs("heihei.ini");  
  335.   
  336.     return 0;  
  337. }</pre><br>  
  338. <br>  
  339. <br>  
  340. <br>  
  341. <br>  
  342. <p></p>  
  343. <map></map>  
  344. <pre></pre>  
  345. <pre></pre>  
  346.   
  347. </pre>  

你可能感兴趣的:(C++,server,File,null,ini)