文章以及源码均为原创,转载请加说明,但请不要私自用于商业
抽空写了个简单的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;
}