本篇内容介绍了“怎么用C++实现简易的.ini配置文件解析器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
在最开始实例化一个IniHelper 可以使用默认的config.ini文件路径,也可以自己传入一个文件路径(读取指定位置的config.ini)
1.saveIniConfig(); 将内存中的配置写入config.ini 2.LogIniConfig() 打印config.ini 3.setIniConfig(const std::string& sectionName,const std::string& keyName,const std::string& value);设置sectionName中keyName为value, 如果原来没有将会添加 4.IniValue getIniConfig(const std::string& sectionName,const std::string& keyName,const std::string& defValue) const; 获取指定位置的config,如果没有,将返回默认值 5.bool removeIniConfig(const std::string& sectionName,const std::string& keyName); 删除指定位置的config 里面使用到的IniValue重载了类型转换运算符,可以直接转换为std::string
编译使用的是VScode + CMake
代码
Util.h
#pragma once #define NAME_SPACE_START(name) namespace name { #define NAME_SPACE_END() } #include <string> #include <map> #ifndef _UTIL_ #define _UTIL_ NAME_SPACE_START(INI) #define REMOVE_SPACE(str) for(auto it=str.begin();it!=str.end();){ if(*it==' ') it=str.erase(it); else break; } #define INI_FILE_PATH "config.ini" class IniValue{ public: friend class IniHelper; IniValue(); IniValue(const bool val); IniValue(const int val); IniValue(const char* val); IniValue(const std::string val); IniValue& operator=(const bool& val); IniValue& operator=(const int& val); IniValue& operator=(const char* val); IniValue& operator=(const std::string& val); operator bool() const; operator int() const; operator std::string() const; private: std::string m_value; }; class IniHelper{ private: std::map<std::string, std::map<std::string, IniValue>> m_map; std::string m_filePath{INI_FILE_PATH}; public: IniHelper(); IniHelper(const std::string& filePath); void saveIniConfig(); void LogIniConfig() const; void setIniConfig(const std::string& sectionName,const std::string& keyName,const std::string& value); IniValue getIniConfig(const std::string& sectionName,const std::string& keyName,const std::string& defValue) const; bool removeIniConfig(const std::string& sectionName,const std::string& keyName); protected: void loadIniFile(); void trim(std::string& str); }; NAME_SPACE_END() #endif //!_UTIL_
Util.cpp
#include "Util.h" #include <algorithm> #include <atomic> #include <cstring> #include <cwchar> #include <exception> #include <fstream> #include <ios> #include <iostream> #include <iterator> #include <locale> #include <map> #include <ostream> #include <sstream> #include <stdlib.h> #include <streambuf> #include <string> NAME_SPACE_START(INI) IniValue::IniValue() { } IniValue::IniValue(const bool val){ m_value=val?"true":"false"; } IniValue::IniValue(const int val){ m_value=std::to_string(val); } IniValue::IniValue(const char* val){ m_value=val; } IniValue::IniValue(const std::string val){ m_value=val; } IniValue& IniValue::operator=(const bool& val){ IniValue temp(val); m_value=temp.m_value; return *this; } IniValue& IniValue::operator=(const int& val){ IniValue temp(val); m_value=temp.m_value; return *this; } IniValue& IniValue::operator=(const char* val){ m_value=val; return *this; } IniValue& IniValue::operator=(const std::string& val){ m_value=val; return *this; } IniValue::operator bool() const{ return m_value=="true"?true:false; } IniValue::operator int() const{ std::stringstream ss(m_value); int res=0; ss>>res; return res; } IniValue::operator std::string() const{ return m_value; } IniHelper::IniHelper(){ loadIniFile(); } IniHelper::IniHelper(const std::string& filePath){ m_filePath=filePath; loadIniFile(); } void IniHelper::saveIniConfig(){ std::fstream file; file.open(m_filePath,std::ios_base::out); if(file.fail()) return; for(auto it=m_map.begin();it!=m_map.end();it++){ std::string sectionName="["+it->first+"] "; file<<sectionName; auto keySection = it->second; for(auto key=keySection.begin();key!=keySection.end();key++){ std::string keyValue=key->first; keyValue.append("=").append(key->second.m_value).append(" "); file<<keyValue; } } file.close(); } void IniHelper::LogIniConfig() const{ for(auto it=m_map.begin();it!=m_map.end();it++){ std::string sectionName="["+it->first+"] "; std::cout<<sectionName; auto keySection = it->second; for(auto key=keySection.begin();key!=keySection.end();key++){ std::string keyValue=key->first; keyValue.append("=").append(key->second.m_value).append(" "); std::cout<<keyValue; } } } void IniHelper::setIniConfig(const std::string& sectionName,const std::string& keyName,const std::string& value){ if(m_map.find(sectionName)==m_map.end()){ std::map<std::string, IniValue> temp; temp[keyName]=value; m_map[sectionName]=temp; } else{ m_map[sectionName][keyName]=value; } } IniValue IniHelper::getIniConfig(const std::string& sectionName,const std::string& keyName,const std::string& defValue) const{ if(m_map.find(sectionName)==m_map.end()) return defValue; std::map<std::string, IniValue> mapping=m_map.at(sectionName); if(mapping.find(keyName)==mapping.end()) return defValue; return mapping[keyName]; } bool IniHelper::removeIniConfig(const std::string& sectionName,const std::string& keyName){ try { if(m_map.find(sectionName)==m_map.end()) return true; auto pos = m_map.at(sectionName).find(keyName); if(pos==m_map.at(sectionName).end()) return true; m_map.at(sectionName).erase(pos); return true; } catch (std::exception ex) { //std::cout<<ex.what()<<std::endl; return false; } } void IniHelper::loadIniFile(){ std::fstream file; file.open(m_filePath,std::ios_base::in); if(file.fail()) return; std::string sectionName="",t=""; while(std::getline(file,t)){ trim(t); //去除前后空格 if(t==" "||t=="") continue; else if(t[0]=='['){ sectionName = t.substr(1,t.size()-2); std::map<std::string, IniValue> p; m_map[sectionName]=p; } else{ if(sectionName=="") continue; int left=0,right=0,equalPos=0; equalPos=t.find("="); if(equalPos==std::string::npos) continue; std::string keyName="",keyValue=""; keyName=t.substr(0,equalPos); keyValue=t.substr(equalPos+1,t.size()-1-equalPos); trim(keyName); trim(keyValue); m_map[sectionName][keyName]=keyValue; } } file.close(); } void IniHelper::trim(std::string& str){ REMOVE_SPACE(str); std::reverse(str.begin(), str.end()); REMOVE_SPACE(str); std::reverse(str.begin(), str.end()); } NAME_SPACE_END()
main.cpp
#include <iostream> #include <string> #include "Util.h" using namespace std; using namespace INI; int main(){ IniHelper file("../config.ini"); //file.removeIniConfig("localhost", "name"); file.setIniConfig("localhost", "name", "cxn"); file.LogIniConfig(); file.saveIniConfig(); return 0; }
运行截图