首页 > 代码库 > 简单的INI解析封装
简单的INI解析封装
简单封装的一个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.77f10 ini.writeInt("glview", "screen_height, 666); // 再次将旧值修改为 66611 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 wrapper10 11 ******************************************************************************/12 #pragma once13 14 #include <list>15 #include <map>16 17 namespace ns_ini18 {19 20 class Section;21 22 /******************************************************************************23 * create : (jacc.kim) [06-13-2017]24 * summary : class IniParser25 ******************************************************************************/26 class IniParser27 {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 = http://www.mamicode.com/section‘s ptr85 typedef std::map <std::string, SectionListIter> SectionMap;86 87 private:88 std::string m_strIniFile; // ini file name89 SectionList m_listSections; // all sections.90 SectionMap m_mapSectionName; // section <--> index mapping.(only reference.)91 92 };//class IniParser93 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 =http://www.mamicode.com/ nullptr; 48 if (nullptr != pcszKey) { 49 auto iter = m_mapParameterKeys.find(pcszKey);; 50 if (m_mapParameterKeys.end() != iter) { 51 pcszRetValue = http://www.mamicode.com/(*(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 =http://www.mamicode.com/ 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 IniParser100 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("]\r\n", 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] = ‘\0‘;177 fputs(szBuffer, pINIFile);178 if (!this->isEndWithN(szBuffer, nEndPos + 1)) {179 fputs("\r\n", pINIFile);180 }181 }182 if (iterend != ++iter) {183 fputs("\r\n", pINIFile);184 }185 }186 fclose(pINIFile);187 pINIFile = nullptr;188 }189 190 return bIsSuccess;191 }192 193 void IniParser::close() {194 this->save();195 this->clear();196 this->setIniFile(nullptr);197 }198 199 unsigned int IniParser::getSectionAmount() const {200 return static_cast<unsigned int>(m_listSections.size());201 }202 203 bool IniParser::isSectionExisted(const char* const pcszSection) const {204 return nullptr != this->getSection(pcszSection);205 }206 207 bool IniParser::isParameterExisted(const char* const pcszSection, const char* const pcszParameter) const {208 auto pSection = this->getSection(pcszSection);209 return nullptr != pSection && pSection->isParameterExisted(pcszParameter);210 }211 212 int IniParser::readInt(const char* const pcszSection, const char* const pcszKey, const int def/* = 0*/) const {213 int retValue =http://www.mamicode.com/ def;214 const char* pcszText = this->readText(pcszSection, pcszKey, nullptr);215 if (nullptr != pcszText) {216 if (1 != sscanf(pcszText, "%d", &retValue)) {217 retValue = http://www.mamicode.com/def; // 读取失败.218 }219 }220 return retValue;221 }222 223 unsigned int IniParser::readUnsignedInt(const char* const pcszSection, const char* const pcszKey, const unsigned int def/* = 0u*/) const {224 unsigned int retValue =http://www.mamicode.com/ def;225 const char* pcszText = this->readText(pcszSection, pcszKey, nullptr);226 if (nullptr != pcszText) {227 if (1 != sscanf(pcszText, "%u", &retValue)) {228 retValue = http://www.mamicode.com/def; // 读取失败.229 }230 }231 return retValue;232 }233 234 bool IniParser::readBool(const char* const pcszSection, const char* const pcszKey, const bool def/* = false*/) const {235 bool retValue =http://www.mamicode.com/ def;236 const char* pcszText = this->readText(pcszSection, pcszKey, nullptr);237 if (nullptr != pcszText) {238 int iTempVal = 0;239 if (1 == sscanf(pcszText, "%d", &iTempVal)) {240 return 0 == iTempVal ? false : true;241 } else if (this->stringEqual(pcszText, "true")) {242 return true;243 } else {244 return false;245 }246 }247 return retValue;248 }249 250 float IniParser::readFloat(const char* const pcszSection, const char* const pcszKey, const float def/* = 0.0f*/) const {251 float retValue =http://www.mamicode.com/ def;252 const char* pcszText = this->readText(pcszSection, pcszKey, nullptr);253 if (nullptr != pcszText) {254 if (1 != sscanf(pcszText, "%f", &retValue)) {255 retValue = http://www.mamicode.com/def; // 读取失败.256 }257 }258 return retValue;259 }260 261 double IniParser::readDouble(const char* const pcszSection, const char* const pcszKey, const double def/* = 0.0*/) const {262 double retValue =http://www.mamicode.com/ def;263 const char* pcszText = this->readText(pcszSection, pcszKey, nullptr);264 if (nullptr != pcszText) {265 if (1 != sscanf(pcszText, "%lf", &retValue)) {266 retValue = http://www.mamicode.com/def; // 读取失败.267 }268 }269 return retValue;270 }271 272 const char* IniParser::readText(const char* const pcszSection, const char* const pcszKey, const char* const def/* = nullptr*/) const {273 const char* pcszRetValue =http://www.mamicode.com/ def;274 auto pSection = this->getSection(pcszSection);275 if (nullptr != pSection) {276 pcszRetValue = http://www.mamicode.com/pSection->read(pcszKey);277 }278 return pcszRetValue;279 }280 281 void IniParser::writeInt(const char* const pcszSection, const char* const pcszKey, const int value) {282 const size_t nBUFF_SIZE = 256;283 char szBuff[nBUFF_SIZE];284 memset((void*)szBuff, 0x0L, nBUFF_SIZE);285 sprintf(szBuff, "%d", value);286 this->writeText(pcszSection, pcszKey, szBuff);287 }288 289 void IniParser::writeUnsignedInt(const char* const pcszSection, const char* const pcszKey, const unsigned int value) {290 const size_t nBUFF_SIZE = 256;291 char szBuff[nBUFF_SIZE];292 memset((void*)szBuff, 0x0L, nBUFF_SIZE);293 sprintf(szBuff, "%u", value);294 this->writeText(pcszSection, pcszKey, szBuff);295 }296 297 void IniParser::writeBool(const char* const pcszSection, const char* const pcszKey, const bool value) {298 const size_t nBUFF_SIZE = 256;299 char szBuff[nBUFF_SIZE];300 memset((void*)szBuff, 0x0L, nBUFF_SIZE);301 sprintf(szBuff, "%d", value ? 1 : 0);302 this->writeText(pcszSection, pcszKey, szBuff);303 }304 305 void IniParser::writeFloat(const char* const pcszSection, const char* const pcszKey, const float value) {306 const size_t nBUFF_SIZE = 256;307 char szBuff[nBUFF_SIZE];308 memset((void*)szBuff, 0x0L, nBUFF_SIZE);309 sprintf(szBuff, "%g", value);310 this->writeText(pcszSection, pcszKey, szBuff);311 }312 313 void IniParser::writeDouble(const char* const pcszSection, const char* const pcszKey, const double value) {314 const size_t nBUFF_SIZE = 256;315 char szBuff[nBUFF_SIZE];316 memset((void*)szBuff, 0x0L, nBUFF_SIZE);317 sprintf(szBuff, "%g", value);318 this->writeText(pcszSection, pcszKey, szBuff);319 }320 321 void IniParser::writeText(const char* const pcszSection, const char* const pcszKey, const char* const value) {322 if (nullptr != pcszSection && nullptr != pcszKey && nullptr != value) {323 auto iter = m_mapSectionName.find(pcszSection);324 Section* pSection = nullptr;325 if (m_mapSectionName.end() == iter) {326 pSection = new (std::nothrow) Section(pcszSection);327 if (nullptr == pSection) {328 return;329 }330 m_listSections.emplace_back(pSection);331 m_mapSectionName[pcszSection] = --m_listSections.end();332 } else {333 pSection = *(iter->second);334 }335 pSection->write(pcszKey, value);336 }337 }338 339 bool IniParser::remove(const char* const pcszSection, const char* const pcszKey) {340 auto bIsSuccess = false;341 if (nullptr != pcszSection) {342 auto iter = m_mapSectionName.find(pcszSection);343 if (m_mapSectionName.end() != iter) {344 auto pSection = *(iter->second);345 if (nullptr != pSection) {346 bIsSuccess = pSection->remove(pcszKey);347 }348 }349 }350 return bIsSuccess;351 }352 353 bool IniParser::remove(const char* const pcszSection) {354 auto bIsSuccess = false;355 if (nullptr != pcszSection) {356 auto iter = m_mapSectionName.find(pcszSection);357 if (m_mapSectionName.end() != iter) {358 auto list_iter = iter->second;359 Section* pSection = *list_iter;360 if (nullptr != pSection) {361 delete pSection;362 pSection = nullptr;363 }364 m_listSections.erase(list_iter);365 m_mapSectionName.erase(iter);366 bIsSuccess = true;367 }368 }369 return bIsSuccess;370 }371 372 void IniParser::clear() {373 auto iter = m_listSections.begin();374 const auto iterend = m_listSections.end();375 Section* pSection = nullptr;376 for (; iterend != iter; ++iter) {377 pSection = *iter;378 if (nullptr != pSection) {379 delete pSection;380 pSection = nullptr;381 }382 }383 m_listSections.clear();384 m_mapSectionName.clear();385 }386 387 Section* IniParser::getSection(const char* const pcszSection) const {388 Section* pRetSection = nullptr;389 auto iter = m_mapSectionName.find(pcszSection);390 if (m_mapSectionName.end() != iter) {391 pRetSection = *(iter->second);392 }393 return pRetSection;394 }395 396 Section& IniParser::operator[](const char* const pcszSection) const {397 auto iter = m_mapSectionName.find(pcszSection);398 return *(*(iter->second));399 }400 401 void IniParser::trimLeft(char*& p, char*& q) {402 if (nullptr != p) {403 while (‘ ‘ == *p && ++p <= q);404 }405 }406 407 void IniParser::trimRight(char*& p, char*& q) {408 if (nullptr != q) {409 while (‘ ‘ == *q && --q >= p);410 }411 }412 413 void IniParser::trim(char*& p, char*& q) {414 this->trimLeft(p, q);415 this->trimRight(p, q);416 }417 418 void IniParser::trimRN0(char*& p, char*& q) {419 if (nullptr != q) {420 while ((‘\0‘ == *q || ‘\r‘ == *q || ‘\n‘ == *q) && --q >= p);421 }422 }423 424 bool IniParser::isEndWithN(const char* p, const size_t nLength) {425 if (0 == nLength) {426 return false;427 }428 const char* q = p + nLength;429 while (‘\0‘ == *q && --q >= p);430 return (q >= p) && (‘\n‘ == *q);431 }432 433 bool IniParser::stringEqual(const char* p, const char* q, int nChar/* = INT_MAX*/) const {434 int n = 0;435 if (p == q) {436 return true;437 }438 while (*p && *q && *p == *q && n < nChar) {439 ++p;440 ++q;441 ++n;442 }443 if ((n == nChar) || (*p == 0 && *q == 0)) {444 return true;445 }446 return false;447 }448 449 bool IniParser::isSectionName(char* p, char* q) {450 if (nullptr == p || nullptr == q) {451 return false;452 }453 return ‘[‘ == *p && ‘]‘ == *q;454 }455 456 char* IniParser::splitKeyValue(char* p, char* q) {457 char* pRetEqualSignPos = p;458 while (‘=‘ != *pRetEqualSignPos && ++pRetEqualSignPos < q);459 return pRetEqualSignPos;460 }461 462 void IniParser::parseIniLine(char* szIniLine) {463 char* p = szIniLine;464 char* q = p + strlen(p);465 this->trimRN0(p, q);466 this->trim(p, q);467 if (p < q) {468 // 只有这种情况才需要处理.因为 p > q,肯定不需要处理,说明全都是空格.如果p = q也不需要处理,因为只有一个字符还需要处理什么?469 *(q + 1) = ‘\0‘;470 if (this->isSectionName(p, q)) {471 *q = ‘\0‘;472 ++p;473 this->addSection(p);474 } else {475 char* szEqualSignPos = this->splitKeyValue(p, q);476 if (szEqualSignPos > p && szEqualSignPos < q) {477 *szEqualSignPos = ‘\0‘;478 ++szEqualSignPos;479 this->addParameter(p, szEqualSignPos);480 }481 }482 }483 }484 485 void IniParser::addSection(char* szSectionName) {486 auto iter = m_mapSectionName.find(szSectionName);487 if (m_mapSectionName.end() != iter) {488 // 已存在489 auto listiter = iter->second;490 m_listSections.emplace_back(*listiter);491 m_listSections.erase(listiter);492 m_mapSectionName.erase(iter);493 m_mapSectionName[szSectionName] = --m_listSections.end();494 return;495 }496 Section* pSection = new (std::nothrow) Section(szSectionName);497 if (nullptr == pSection) {498 return;499 }500 m_listSections.emplace_back(pSection);501 m_mapSectionName[szSectionName] = --m_listSections.end();502 }503 504 void IniParser::addParameter(char* szKey, char* szValue) {505 if (m_listSections.empty()) {506 return;507 }508 auto pSection = m_listSections.back();509 pSection->write(szKey, szValue);510 }511 512 }//namespace ns_ini
如果对该封装有改进或不当之处,欢迎指定、交流!
简单的INI解析封装
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。