文章以及源码均为原创,转载请加说明,但请不要私自用于商业
抽空写了个简单的ini文件操作源码,欢迎各位阅读,也欢迎来讨论
/**************************************** 文件名称:inifile.h 作者:木马小Z 创建日期:20210906 版本:V1.0 ****************************************/ #include <iostream> #include <string> #define ERR_MES_1 "输入值不合法" #define ERR_MES_2 "打开文件失败" #define ERR_MES_3 "配置项不存在" const char TYPE_NULL = '0'; const char TYPE_SECTION = '1'; const char TYPE_PARAMETER = '2'; const char TYPE_COMMENT = '3'; typedef struct IniNode { char m_Type; std::string m_Text; IniNode* m_pPrev; IniNode* m_pNext; }IniNode,*pIniNode; typedef struct IniSec { pIniNode m_pSection; pIniNode m_pParameter; std::string m_SectionText; std::string m_ParameterText; }IniSec, *pIniSec; class IniFile { public: IniFile(); ~IniFile(); /**************************************** 函数名称:ReadIniFile 参数列表:FilePathName 文件目录 用途 :加载ini文件 返回值 :成功true 失败false ****************************************/ bool ReadIniFile(const char *FilePathName); /**************************************** 函数名称:WriteIniFile 参数列表:FilePathName 文件目录 用途 :写入ini文件 返回值 :成功true 失败false ****************************************/ bool WriteIniFile(const char *FilePathName); /**************************************** 函数名称:WriteParameter 参数列表:Section 节 Key 键 Value 值 用途 :增加或者更新参数 返回值 :成功true 失败false ****************************************/ bool WriteParameter(const char*Section, const char*Key, const char*Value); bool WriteParameter(const char*Section, const char*Key, const bool Value); bool WriteParameter(const char*Section, const char*Key, const int Value); bool WriteParameter(const char*Section, const char*Key, const double Value); /**************************************** 函数名称:ReadParameter 参数列表:Section 节 Key 键 Default 默认值 用途 :读取键值 返回值 :存在返回键值,不存在返回默认值 ****************************************/ std::string ReadParameter(const char*Section, const char*Key, const char*Default); bool ReadParameter(const char*Section, const char*Key, const bool Default); int ReadParameter(const char*Section, const char*Key, const int Default); double ReadParameter(const char*Section, const char*Key, const double Default); /**************************************** 函数名称:DeleteParameter 参数列表:Section 节 Key 键 用途 :删除参数 返回值 :成功true 失败false ****************************************/ bool DeleteParameter(const char*Section, const char*Key); /**************************************** 函数名称:DeleteSection 参数列表:Section 节 用途 :删除节和节的所有参数 返回值 :成功true 失败false ****************************************/ bool DeleteSection(const char*Section); int GetErrCode(); std::string GetErrMes(); protected: void FreeIniList(); void CreateIniNode(); void Trim(char*Buffer); pIniNode FindSection(const char*Section); pIniSec FindParameter(const char*Section, const char*Key); void AddIniNode(char Type, const char * Text); bool WriteParameterPublic(const char*Section, const char*Key, const char*Value); std::string ReadParameterPublic(const char*Section, const char*Key, const char*Default); private: FILE *m_pIniFileHandle; pIniNode m_pIniList; pIniNode m_pCurIniNode; int m_LastErrCode; std::string m_LastErrMes; };
/**************************************** 文件名称:inifile.cpp 作者:木马小Z 创建日期:20210906 版本:V1.0 ****************************************/ #include "inifile.h" IniFile::IniFile() { m_LastErrCode = 0; m_LastErrMes = ""; m_pCurIniNode = nullptr; m_pIniFileHandle = nullptr; m_pIniList = nullptr; } IniFile::~IniFile() { FreeIniList(); fclose(m_pIniFileHandle); } int IniFile::GetErrCode() { return m_LastErrCode; } std::string IniFile::GetErrMes() { return m_LastErrMes; } bool IniFile::ReadIniFile(const char* FilePathName) { if (!strcmp(FilePathName, "")) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return false; } if (!(m_pIniFileHandle = fopen(FilePathName, "r"))) { m_LastErrCode = 2; m_LastErrMes = ERR_MES_2; return false; } FreeIniList(); char filebuf[256] = { 0 }; char *pchr = nullptr; while (fgets(filebuf, 256, m_pIniFileHandle)) { Trim(filebuf); CreateIniNode(); if (';' == filebuf[0]) { m_pCurIniNode->m_Type = TYPE_COMMENT; } else if ('[' == filebuf[0] && strchr(filebuf, ']')) { m_pCurIniNode->m_Type = TYPE_SECTION; } else if (strchr(filebuf, '=')) { m_pCurIniNode->m_Type = TYPE_PARAMETER; } else { m_pCurIniNode->m_Type = TYPE_NULL; } m_pCurIniNode->m_Text = filebuf; } fclose(m_pIniFileHandle); return true; } bool IniFile::WriteIniFile(const char *FilePathName) { if (!strcmp(FilePathName, "")) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return false; } char FilePathNameBat[256] = { 0 }; strcpy(FilePathNameBat, FilePathName); strcat(FilePathNameBat, ".bak"); FILE *FileIniTemp = fopen(FilePathName, "r"); FILE *FileBatTemp = fopen(FilePathNameBat, "w"); if (!FileIniTemp || !FileBatTemp) { m_LastErrCode = 2; m_LastErrMes = ERR_MES_2; return false; } char FileStr[256] = { 0 }; while (fgets(FileStr, 256, FileIniTemp)) { fprintf(FileBatTemp, "%s", FileStr); } fclose(FileIniTemp); fclose(FileBatTemp); if (!(m_pIniFileHandle = fopen(FilePathName, "w"))) { m_LastErrCode = 2; m_LastErrMes = ERR_MES_2; return false; } m_pCurIniNode = m_pIniList; while (m_pCurIniNode) { fprintf(m_pIniFileHandle, "%s\n", m_pCurIniNode->m_Text.data()); m_pCurIniNode = m_pCurIniNode->m_pNext; } fclose(m_pIniFileHandle); return true; } bool IniFile::WriteParameter(const char*Section, const char*Key, const char*Value) { return WriteParameterPublic(Section, Key, Value); } bool IniFile::WriteParameter(const char*Section, const char*Key, const bool Value) { char StrValue[256] = { 0 }; itoa(Value, StrValue,2); return WriteParameterPublic(Section, Key, StrValue); } bool IniFile::WriteParameter(const char*Section, const char*Key, const int Value) { char StrValue[256] = { 0 }; itoa(Value, StrValue, 10); return WriteParameterPublic(Section, Key, StrValue); } bool IniFile::WriteParameter(const char*Section, const char*Key, const double Value) { char StrValue[256] = { 0 }; sprintf_s(StrValue, "%f", Value); return WriteParameterPublic(Section, Key, StrValue); } std::string IniFile::ReadParameter(const char*Section, const char*Key, const char*Default) { return ReadParameterPublic(Section, Key, Default); } bool IniFile::ReadParameter(const char*Section, const char*Key, const bool Default) { char DefaultString[2] = { 0 }; if (Default) { DefaultString[0] = '1'; } else { DefaultString[0] = '0'; } std::string RetStr = ReadParameterPublic(Section, Key, DefaultString); return atoi(RetStr.data()); } int IniFile::ReadParameter(const char*Section, const char*Key, const int Default) { char DefaultString[256] = { 0 }; itoa(Default, DefaultString, 10); std::string RetStr = ReadParameterPublic(Section, Key, DefaultString); return atoi(RetStr.data()); } double IniFile::ReadParameter(const char*Section, const char*Key, const double Default) { char DefaultString[256] = { 0 }; sprintf_s(DefaultString, "%f", Default); std::string RetStr = ReadParameterPublic(Section, Key, DefaultString); return atof(RetStr.data()); } bool IniFile::DeleteParameter(const char*Section, const char*Key) { if (!strcmp(Section, "") || !strcmp(Key, "")) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return false; } pIniSec pIniSecTemp = FindParameter(Section, Key); if (!pIniSecTemp) { m_LastErrCode = 3; m_LastErrMes = ERR_MES_3; return false; } m_pCurIniNode = pIniSecTemp->m_pParameter; m_pCurIniNode->m_pPrev->m_pNext = m_pCurIniNode->m_pNext; if (m_pCurIniNode->m_pNext) { m_pCurIniNode->m_pNext->m_pPrev = m_pCurIniNode->m_pPrev; } delete m_pCurIniNode; delete pIniSecTemp; return true; } bool IniFile::DeleteSection(const char*Section) { if (!strcmp(Section, "") ) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return false; } pIniNode pSectionIniNodeTemp = FindSection(Section); if (!pSectionIniNodeTemp) { m_LastErrCode = 3; m_LastErrMes = ERR_MES_3; return false; } pIniNode pCurNextIniNode = nullptr; m_pCurIniNode = pSectionIniNodeTemp->m_pNext; while (m_pCurIniNode&&m_pCurIniNode->m_Type==TYPE_PARAMETER) { pCurNextIniNode = m_pCurIniNode->m_pNext; m_pCurIniNode->m_pPrev->m_pNext = m_pCurIniNode->m_pNext; if (m_pCurIniNode->m_pNext) { m_pCurIniNode->m_pNext->m_pPrev = m_pCurIniNode->m_pPrev; } delete m_pCurIniNode; m_pCurIniNode = pCurNextIniNode; } m_pCurIniNode = pSectionIniNodeTemp; m_pCurIniNode->m_pPrev->m_pNext = m_pCurIniNode->m_pNext; if (m_pCurIniNode->m_pNext) { m_pCurIniNode->m_pNext->m_pPrev = m_pCurIniNode->m_pPrev; } delete m_pCurIniNode; return true; } void IniFile::FreeIniList() { if (nullptr == m_pIniList) { return; } pIniNode pNextIniNodeTemp = nullptr; while (nullptr != m_pIniList) { pNextIniNodeTemp = m_pIniList->m_pNext; delete m_pIniList; m_pIniList = pNextIniNodeTemp; } } void IniFile::CreateIniNode() { pIniNode pIniNodeTemp = new IniNode; memset(pIniNodeTemp, 0, sizeof(IniNode)); if (nullptr == m_pIniList) { m_pIniList = pIniNodeTemp; m_pCurIniNode = pIniNodeTemp; return; } m_pCurIniNode = m_pIniList; while (m_pCurIniNode->m_pNext) { m_pCurIniNode = m_pCurIniNode->m_pNext; } m_pCurIniNode->m_pNext = pIniNodeTemp; pIniNodeTemp->m_pPrev = m_pCurIniNode; m_pCurIniNode = pIniNodeTemp; } void IniFile::Trim(char*Buffer) { int i = 0; int len = strlen(Buffer); for (i = len - 1; i >= 0; i--) { if (' ' != Buffer[i] && '\t' != Buffer[i] && '\n' != Buffer[i]) { break; } Buffer[i] = 0; } for (i = 0; i < len; i++) { if (' ' != Buffer[i] && '\t' != Buffer[i] && '\n' != Buffer[i]) { break; } } if (0 != i) { strncpy(Buffer, Buffer + i, len - i); Buffer[len - i] = 0; } } pIniNode IniFile::FindSection(const char*Section) { m_pCurIniNode = m_pIniList; while (m_pCurIniNode) { if (!strcmp(m_pCurIniNode->m_Text.data(), Section) && m_pCurIniNode->m_Type == TYPE_SECTION) { return m_pCurIniNode; } m_pCurIniNode = m_pCurIniNode->m_pNext; } return nullptr; } pIniSec IniFile::FindParameter(const char*Section, const char*Key) { m_pCurIniNode = m_pIniList; pIniSec pIniSecTemp = new IniSec; char Buf[256] = { 0 }; char*pChr = nullptr; while (m_pCurIniNode) { if (!strcmp(m_pCurIniNode->m_Text.data(), Section) && m_pCurIniNode->m_Type == TYPE_SECTION) { pIniSecTemp->m_pSection = m_pCurIniNode; pIniSecTemp->m_SectionText = m_pCurIniNode->m_Text; m_pCurIniNode = m_pCurIniNode->m_pNext; while (m_pCurIniNode&&m_pCurIniNode->m_Type==TYPE_PARAMETER) { strcpy(Buf, m_pCurIniNode->m_Text.data()); if (pChr = strchr(Buf, '=')) { *pChr = 0; Trim(Buf); if (!strcmp(Buf, Key)) { pIniSecTemp->m_pParameter = m_pCurIniNode; pIniSecTemp->m_ParameterText = m_pCurIniNode->m_Text; return pIniSecTemp; } } m_pCurIniNode = m_pCurIniNode->m_pNext; } break; } m_pCurIniNode = m_pCurIniNode->m_pNext; } delete pIniSecTemp; return nullptr; } void IniFile::AddIniNode(char Type, const char * Text) { if (Type==TYPE_SECTION) { m_pCurIniNode->m_Type = TYPE_SECTION; m_pCurIniNode->m_Text = Text; } else if (Type == TYPE_PARAMETER) { m_pCurIniNode->m_Type = TYPE_PARAMETER; m_pCurIniNode->m_Text = Text; } return; } bool IniFile::WriteParameterPublic(const char*Section, const char*Key, const char*Value) { if (!strcmp(Section, "") || !strcmp(Key, "") || !strcmp(Value, "")) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return false; } char Parameter[256] = { 0 }; strcpy(Parameter, Key); strcat(Parameter, "="); strcat(Parameter, Value); pIniNode pSectionNodeTemp = FindSection(Section); pIniSec pIniSecTemp = nullptr; if (!pSectionNodeTemp) { CreateIniNode(); AddIniNode(TYPE_SECTION, Section); CreateIniNode(); AddIniNode(TYPE_PARAMETER, Parameter); } else { if (!(pIniSecTemp = FindParameter(Section, Key))) { pIniNode pIniNodeTemp = new IniNode; memset(pIniNodeTemp, 0, sizeof(IniNode)); pIniNodeTemp->m_pNext = pSectionNodeTemp->m_pNext; pSectionNodeTemp->m_pNext = pIniNodeTemp; if (pIniNodeTemp->m_pNext) { pIniNodeTemp->m_pNext->m_pPrev = pIniNodeTemp; } pIniNodeTemp->m_pPrev = pSectionNodeTemp; m_pCurIniNode = pIniNodeTemp; AddIniNode(TYPE_PARAMETER, Parameter); } else { m_pCurIniNode = pIniSecTemp->m_pParameter; AddIniNode(TYPE_PARAMETER, Parameter); } } delete pIniSecTemp; pIniSecTemp = nullptr; return true; } std::string IniFile::ReadParameterPublic(const char*Section, const char*Key, const char*Default) { if (!strcmp(Section, "") || !strcmp(Key, "") || !strcmp(Default, "")) { m_LastErrCode = 1; m_LastErrMes = ERR_MES_1; return false; } std::string Ret; pIniSec pIniSecTemp = FindParameter(Section, Key); char *pChr = nullptr; if (pIniSecTemp) { char Buf[256] = { 0 }; strcpy(Buf, pIniSecTemp->m_ParameterText.data()); if (pChr = strchr(Buf, '=')) { strcpy(Buf, pChr + 1); } Ret = Buf; } else { Ret = Default; } delete pIniSecTemp; return Ret; }