简单封装的一个ini解析处理类(支持跨平台)。支持功能:
- 加载并解析指定ini文件中的配置;
- 读取指定 section 下的指定 key 的值。提示:支持按数值型读取,或按文本类型读取;
使用示例:
1 auto fWidth = 480.0f; 2 auto fHeight = 320.0f; 3 4 ns_ini::IniParser ini; 5 ini.open(strConfigFile.c_str()); 6 fWidth = ini.readFloat("glview", "screen_width", fWidth); 7 fHeight = ini.readFloat("glview", "screen_height", fHeight);
- 支持新段、项、值写入;提示:如果写入的项是已经存在的,则为修改旧项值;
示例:
1 auto fWidth = 480.0f; 2 auto fHeight = 320.0f; 3 4 ns_ini::IniParser ini; 5 ini.open(strConfigFile.c_str()); 6 fWidth = ini.readFloat("glview", "screen_width", fWidth); 7 fHeight = ini.readFloat("glview", "screen_height", fHeight); 8 9 ini.writeFloat("glview", "screen_height, 777.77f); // 将旧值修改为 777.77f 10 ini.writeInt("glview", "screen_height, 666); // 再次将旧值修改为 666 11 ini.writeText("glview", "screen_height, "jacc.kim"); // 再次将旧值修改为 文本"jacc.kim"
源码如下:
1 /****************************************************************************** 2 3 I'm jacc.kim 4 5 CreateDate: 2017-06-13 17:12:16 6 FileName : JKIniParser.h 7 Version : 1.00 8 Author : jacc.kim 9 Summary : ini parser wrapper 10 11 ******************************************************************************/ 12 #pragma once 13 14 #include <list> 15 #include <map> 16 17 namespace ns_ini 18 { 19 20 class Section; 21 22 /****************************************************************************** 23 * create : (jacc.kim) [06-13-2017] 24 * summary : class IniParser 25 ******************************************************************************/ 26 class IniParser 27 { 28 public: 29 void setIniFile(const char* const pcszIniFile); 30 bool open(const char* const pcszIniFile = nullptr); 31 bool save(const char* const pcszIniFile = nullptr); 32 void close(); 33 34 unsigned int getSectionAmount() const; 35 bool isSectionExisted(const char* const pcszSection) const; 36 bool isParameterExisted(const char* const pcszSection, const char* const pcszParameter) const; 37 38 int readInt(const char* const pcszSection, const char* const pcszKey, const int def = 0) const; 39 unsigned int readUnsignedInt(const char* const pcszSection, const char* const pcszKey, const unsigned int def = 0u) const; 40 bool readBool(const char* const pcszSection, const char* const pcszKey, const bool def = false) const; 41 float readFloat(const char* const pcszSection, const char* const pcszKey, const float def = 0.0f) const; 42 double readDouble(const char* const pcszSection, const char* const pcszKey, const double def = 0.0) const; 43 const char* readText(const char* const pcszSection, const char* const pcszKey, const char* const def = nullptr) const; 44 45 // !!!note: write existed section & key, the old value will be replaced. 46 void writeInt(const char* const pcszSection, const char* const pcszKey, const int value); 47 void writeUnsignedInt(const char* const pcszSection, const char* const pcszKey, const unsigned int value); 48 void writeBool(const char* const pcszSection, const char* const pcszKey, const bool value); 49 void writeFloat(const char* const pcszSection, const char* const pcszKey, const float value); 50 void writeDouble(const char* const pcszSection, const char* const pcszKey, const double value); 51 void writeText(const char* const pcszSection, const char* const pcszKey, const char* const value); 52 53 bool remove(const char* const pcszSection, const char* const pcszKey); 54 bool remove(const char* const pcszSection); 55 void clear(); 56 57 public: 58 IniParser(); 59 ~IniParser(); 60 61 Section* getSection(const char* const pcszSection) const; 62 Section& operator[](const char* const pcszSection) const; 63 64 private: 65 IniParser(const IniParser& rhs)/* = delete*/; 66 IniParser& operator=(const IniParser& rhs)/* = delete*/; 67 68 void trimLeft(char*& p, char*& q); 69 void trimRight(char*& p, char*& q); 70 void trim(char*& p, char*& q); 71 void trimRN0(char*& p, char*& q); 72 bool isEndWithN(const char* p, const size_t nLength); 73 bool stringEqual(const char* p, const char* q, int nChar = INT_MAX) const; 74 bool isSectionName(char* p, char* q); 75 char* splitKeyValue(char* p, char* q); 76 void parseIniLine(char* szIniLine); 77 void addSection(char* szSectionName); 78 void addParameter(char* szKey, char* szValue); 79 80 private: 81 typedef std::list<Section*> SectionList; 82 typedef SectionList::iterator SectionListIter; 83 84 // key = section name, value = section's ptr 85 typedef std::map <std::string, SectionListIter> SectionMap; 86 87 private: 88 std::string m_strIniFile; // ini file name 89 SectionList m_listSections; // all sections. 90 SectionMap m_mapSectionName; // section <--> index mapping.(only reference.) 91 92 };//class IniParser 93 94 }//namespace ns_ini
1 #include "JKIniParser.h" 2 3 namespace ns_ini 4 { 5 6 /****************************************************************************** 7 * create : (jacc.kim) [06-13-2017] 8 * summary : class Section 9 ******************************************************************************/ 10 class Section 11 { 12 public: 13 struct Parameter 14 { 15 std::string key; 16 std::string value; 17 };//struct Parameter 18 19 typedef std::list<Parameter> ParameterList; 20 typedef ParameterList::iterator ParameterListIter; 21 typedef std::map<std::string, ParameterListIter> ParameterMap; 22 23 public: 24 Section(const char* pcszSectionName) : m_strSectionName (pcszSectionName) 25 , m_listParameters () 26 , m_mapParameterKeys() 27 {} 28 29 ~Section() { 30 this->clear(); 31 } 32 33 const char* getSectionName() const { 34 return m_strSectionName.c_str(); 35 } 36 37 bool isParameterExisted(const char* const pcszKey) const { 38 return m_mapParameterKeys.find(pcszKey) != m_mapParameterKeys.end(); 39 } 40 41 Parameter& operator[](const char* const pcszKey) const { 42 auto iter = m_mapParameterKeys.find(pcszKey); 43 return *(iter->second); 44 } 45 46 const char* read(const char* const pcszKey) { 47 const char* pcszRetValue = nullptr; 48 if (nullptr != pcszKey) { 49 auto iter = m_mapParameterKeys.find(pcszKey);; 50 if (m_mapParameterKeys.end() != iter) { 51 pcszRetValue = (*(iter->second)).value.c_str(); 52 } 53 } 54 return pcszRetValue; 55 } 56 57 bool write(const char* const pcszKey, const char* const pcszValue) { 58 auto iter = m_mapParameterKeys.find(pcszKey); 59 if (m_mapParameterKeys.end() == iter) { 60 Parameter param = { pcszKey, pcszValue }; 61 m_listParameters.emplace_back(param); 62 m_mapParameterKeys[pcszKey] = --m_listParameters.end(); 63 return true; 64 } 65 (*this)[pcszKey].value = pcszValue; 66 return true; 67 } 68 69 bool remove(const char* pcszKey) { 70 auto bIsSuccess = false; 71 if (nullptr != pcszKey) { 72 auto iter = m_mapParameterKeys.find(pcszKey); 73 if (m_mapParameterKeys.end() != iter) { 74 m_listParameters.erase(iter->second); 75 m_mapParameterKeys.erase(iter); 76 bIsSuccess = true; 77 } 78 } 79 return bIsSuccess; 80 } 81 82 void clear() { 83 m_listParameters.clear(); 84 m_mapParameterKeys.clear(); 85 } 86 87 ParameterList& getAllParameters() { 88 return m_listParameters; 89 } 90 91 private: 92 std::string m_strSectionName; 93 ParameterList m_listParameters; 94 ParameterMap m_mapParameterKeys; 95 96 };//class Section 97 98 /////////////////////////////////////////////////////////////////////////////// 99 // class IniParser 100 IniParser::IniParser() : m_strIniFile ("") 101 , m_listSections () 102 , m_mapSectionName() 103 { 104 105 } 106 107 IniParser::~IniParser() { 108 this->clear(); 109 } 110 111 void IniParser::setIniFile(const char* const pcszIniFile) { 112 if (nullptr == pcszIniFile) { 113 return; 114 } 115 m_strIniFile = pcszIniFile; 116 } 117 118 bool IniParser::open(const char* const pcszIniFile/* = nullptr*/) { 119 auto bIsSuccess = false; 120 const char* pcszOpenFile = nullptr != pcszIniFile ? pcszIniFile : m_strIniFile.c_str(); 121 if (nullptr == pcszOpenFile) { 122 return bIsSuccess; 123 } 124 if (nullptr != pcszIniFile) { 125 this->setIniFile(pcszIniFile); 126 } 127 this->clear(); 128 auto pINIFile = fopen(pcszIniFile, "rb"); 129 if (nullptr != pINIFile) { 130 bIsSuccess = true; 131 const size_t nBUFF_SIZE = 2048; 132 char szBuff[nBUFF_SIZE]; 133 while (!feof(pINIFile)) { 134 memset((void*)szBuff, 0x0L, nBUFF_SIZE); 135 fgets(szBuff, nBUFF_SIZE, pINIFile); 136 this->parseIniLine(szBuff); 137 } 138 fclose(pINIFile); 139 pINIFile = nullptr; 140 } 141 142 return bIsSuccess; 143 } 144 145 bool IniParser::save(const char* const pcszIniFile/* = nullptr*/) { 146 auto bIsSuccess = false; 147 const char* pcszSaveFile = nullptr != pcszIniFile ? pcszIniFile : m_strIniFile.c_str(); 148 if (nullptr == pcszSaveFile) { 149 return bIsSuccess; // 没有可保存的路径 150 } 151 ::remove(pcszSaveFile); 152 auto pINIFile = fopen(pcszSaveFile, "ab+"); 153 if (nullptr != pINIFile) { 154 bIsSuccess = true; 155 auto iter = m_listSections.begin(); 156 const auto iterend = m_listSections.end(); 157 const size_t nBUFF_SIZE = 2048; 158 char szBuffer[nBUFF_SIZE]; 159 Section* pSection = nullptr; 160 for (; iterend != iter;/* ++iter*/) { 161 pSection = *iter; 162 const char* pcszSectionName = pSection->getSectionName(); 163 fputs("[", pINIFile); 164 fputs(pcszSectionName, pINIFile); 165 fputs("] ", pINIFile); 166 auto& allParameters = (*iter)->getAllParameters(); 167 auto listiter = allParameters.begin(); 168 const auto listiterend = allParameters.end(); 169 for (; listiterend != listiter; ++listiter) { 170 auto& param = *listiter; 171 memset((void*)szBuffer, 0x0L, nBUFF_SIZE); 172 memcpy(szBuffer, param.key.c_str(), param.key.length()); 173 szBuffer[param.key.length()] = '='; 174 memcpy(szBuffer + param.key.length() + 1, param.value.c_str(), param.value.length()); 175 const auto nEndPos = param.key.length() + 1 + param.value.length(); 176 szBuffer[nEndPos + 1] = '