最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++解析ini文件的實(shí)現(xiàn)方法

 更新時(shí)間:2024年08月06日 08:45:32   作者:長(zhǎng)弓聊編程  
在C++編程中,有時(shí)我們需要處理配置文件來存儲(chǔ)應(yīng)用程序的設(shè)置和參數(shù),而INI文件是一種常見的選擇,這篇文章主要給大家介紹了關(guān)于C++解析ini文件的實(shí)現(xiàn)方法,需要的朋友可以參考下

這篇文章簡(jiǎn)單討論一下ini文件。

一.什么是ini文件

ini文件其實(shí)就是一種配置文件,常見于Windows的系統(tǒng)配置文件,當(dāng)然也可以是其他用途,你的用法你說了算。

二.ini文件的格式一般是什么樣的

看個(gè)例子

;這是注釋
[section1]
key1=value1
key2=value2
[section2]
key3=value3
key4=value4

ini文件包括節(jié)(section)、鍵值對(duì)(通常稱為參數(shù),parameter)和注釋(comment)。

1.節(jié)

1.每一個(gè)section包含若干個(gè)parameter。

2.每一個(gè)section獨(dú)占一行,名稱由[]包圍,比如[sectionName]。

3.每一個(gè)section的生效范圍,從當(dāng)前section開始到下一個(gè)section的開始(或者文件結(jié)尾),這其中所有的parameter都屬于這個(gè)section。

4.section不應(yīng)該重復(fù)。

2.參數(shù)

1.parameter以鍵值對(duì)的形式存在,比如key=value。

2.同一個(gè)section中的parameter不應(yīng)該重復(fù)。

3.注釋

1.注釋用;表示。

2.注釋獨(dú)占一行。

三.C++實(shí)現(xiàn)ini文件的解析

重點(diǎn)來了,這里展示一種C++解析ini文件的簡(jiǎn)易代碼寫法,主要是描述一種解析的思維,大致測(cè)試過了。

直接看代碼

//inifile.h

#ifndef INIFILE_H
#define INIFILE_H

#include <iostream>
#include <string>

#define ERR_MES_1 "輸入值不合法"
#define ERR_MES_2 "打開文件失敗"
#define ERR_MES_3 "配置項(xiàng)不存在"

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();
	bool ReadIniFile(const char* FilePathName);
	bool WriteIniFile(const char* FilePathName);
	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);
	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);
	bool DeleteParameter(const char* Section, const char* Key);
	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;
};

#endif // !INIFILE_H
//inifile.cpp

#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 {};
	}
	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;
}

四.其他

說一個(gè)小技巧,如果擔(dān)心格式寫的不對(duì),可以用熟悉的編輯器中設(shè)置文檔格式這個(gè)功能調(diào)整一下,當(dāng)然調(diào)整之后也要進(jìn)行確認(rèn)。

到此這篇關(guān)于C++解析ini文件實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C++解析ini文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Qt消除警告的實(shí)現(xiàn)示例

    Qt消除警告的實(shí)現(xiàn)示例

    Qt5 和 Qt6 之間存在一些差異,導(dǎo)致在編譯時(shí)可能產(chǎn)生警告,為了消除這些警告,Qt 提供了一些宏定義來幫助你在代碼中處理這些差異,本文主要介紹了Qt消除警告的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2023-09-09
  • Qt連接數(shù)據(jù)庫(kù)并實(shí)現(xiàn)增刪改查操作

    Qt連接數(shù)據(jù)庫(kù)并實(shí)現(xiàn)增刪改查操作

    這篇文章主要為大家詳細(xì)介紹了Qt如何連接數(shù)據(jù)庫(kù)并實(shí)現(xiàn)增刪改查等基本操作,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-09-09
  • 淺析C++中模板的那點(diǎn)事

    淺析C++中模板的那點(diǎn)事

    C++中的模板可分為函數(shù)模板和類模板,而把函數(shù)模板的具體化稱為模板函數(shù),把類模板的具體化成為模板類。下面讓我們分別看看什么是函數(shù)模板和類模板吧
    2013-09-09
  • C++中關(guān)于委派(Delegates)的實(shí)現(xiàn)示例

    C++中關(guān)于委派(Delegates)的實(shí)現(xiàn)示例

    這篇文章主要介紹了C++中關(guān)于委派(Delegates)的實(shí)現(xiàn)示例,針對(duì)C++11的一些新特性進(jìn)行講解,需要的朋友可以參考下
    2015-07-07
  • C語言 pthread_create() 函數(shù)講解

    C語言 pthread_create() 函數(shù)講解

    這篇文章主要介紹了C語言 pthread_create() 函數(shù)講解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C語言實(shí)現(xiàn)最全自動(dòng)售貨機(jī)

    C語言實(shí)現(xiàn)最全自動(dòng)售貨機(jī)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)最全自動(dòng)售貨機(jī),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • opencv實(shí)現(xiàn)三幀差法解析

    opencv實(shí)現(xiàn)三幀差法解析

    這篇文章主要介紹了opencv實(shí)現(xiàn)三幀差法的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • C++11 Unicode編碼轉(zhuǎn)換

    C++11 Unicode編碼轉(zhuǎn)換

    這篇文章主要介紹了C++11 Unicode編碼轉(zhuǎn)換的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c++11,感興趣的朋友可以了解下
    2020-08-08
  • C++如何獲取鼠標(biāo)點(diǎn)擊位置

    C++如何獲取鼠標(biāo)點(diǎn)擊位置

    這篇文章主要介紹了C++如何獲取鼠標(biāo)點(diǎn)擊位置問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C++利用容器查找重復(fù)列功能實(shí)現(xiàn)

    C++利用容器查找重復(fù)列功能實(shí)現(xiàn)

    本文將詳細(xì)介紹c++容器簡(jiǎn)介,c++容器的比較 與操作實(shí)例,需要了解更多的朋友可以參考下
    2012-11-11

最新評(píng)論

黎城县| 沂水县| 辛集市| 崇信县| 高淳县| 青冈县| 安福县| 安徽省| 衢州市| 烟台市| 鹤岗市| 临漳县| 鄯善县| 苏尼特左旗| 都江堰市| 绥江县| 江北区| 奇台县| 井冈山市| 土默特左旗| 柳河县| 石阡县| 利川市| 鄂伦春自治旗| 南宫市| 监利县| 陇南市| 华容县| 禄劝| 三门县| 祁阳县| 宣城市| 开封县| 苍南县| 兰考县| 仁寿县| 台北县| 辽宁省| 阳江市| 和平县| 鲁甸县|