C++ 读配置文件

大家好,我是 DongGu ,是一名软件工程专业大二的学生,写博客一方面是为了记录自己的学习过程,把自己犯的错误进行分享。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!有任何问题可以评论 或者 ___>
QQ联系(1521839703)

C++ 读配置文件

  1. 关键定义好配置文件的格式
  2. 再按规则提取配置项, 和配置属性

#include<vector>
#include<iostream>
#include<Windows.h>
#include<algorithm>

using namespace std;

typedef struct _CConfItem
{
	char ItemName[50];
	char ItemContent[500];
}CConfItem, * LPCConfItem;


class CConfig
{
private:
	CConfig() = default;
public:
	~CConfig();
private:
	static CConfig* m_instance;

public:
	static CConfig* GetInstance()
	{
		if (m_instance == NULL)
		{
			if (m_instance == NULL)
			{
				m_instance = new CConfig();
				static CGarhuishou cl;
			}
		}
		return m_instance;
	}
	class CGarhuishou  //类中套类,用于释放对象
	{
	public:
		~CGarhuishou()
		{
			if (CConfig::m_instance)
			{
				delete CConfig::m_instance;
				CConfig::m_instance = NULL;
			}
		}
	};
	//---------------------------------------------------
public:
	bool Load(const char* pconfName); //装载配置文件
	const char* GetString(const char* p_itemname);
	int  GetIntDefault(const char* p_itemname, const int def);

public:
	std::vector<LPCConfItem> m_ConfigItemList; //存储配置信息的列表

};

CConfig* CConfig::m_instance = NULL;

CConfig::~CConfig()
{
	for (auto pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos)
	{
		delete (*pos);
	}//end for
	m_ConfigItemList.clear();
	return;
}

//截取字符串尾部空格
void Rtrim(char* string)
{
	size_t len = 0;
	if (string == NULL)
		return;

	len = strlen(string);
	while (len > 0 && string[len - 1] == ' ')   //位置换一下   
		string[--len] = '\0';
	return;
}

//截取字符串首部空格
void Ltrim(char* string)
{
	size_t len = 0;
	len = strlen(string);
	char* p_tmp = string;
	if ((*p_tmp) != ' ') //不是以空格开头
		return;
	//找第一个不为空格的
	while ((*p_tmp) != '\0')
	{
		if ((*p_tmp) == ' ')
			p_tmp++;
		else
			break;
	}   
	if ((*p_tmp) == '\0') //全是空格
	{
		*string = '\0';
		return;
	}
	char* p_tmp2 = string;
	while ((*p_tmp) != '\0')
	{
		(*p_tmp2) = (*p_tmp);
		p_tmp++;
		p_tmp2++;
	}
	(*p_tmp2) = '\0';
	return;
}

//装载配置文件
bool CConfig::Load(const char* pconfName)
{
	FILE* fp;
	fp = fopen(pconfName, "r");
	if (fp == NULL)
		return false;

	//每一行配置文件读出来都放这里
	char  linebuf[501];   //每行配置都不要太长,保持<500字符内,防止出现问题

	//走到这里,文件打开成功 
	while (!feof(fp))  //检查文件是否结束 ,没有结束则条件成立
	{
		if (fgets(linebuf, 500, fp) == NULL) //从文件中读数据,每次读一行,一行最多不要超过500个字符 
			continue;
		//printf("--- %s\n", linebuf);

		if (linebuf[0] == 0)
			continue;

		//处理注释行
		if (*linebuf == ';' || *linebuf == ' ' || *linebuf == '#' || *linebuf == '\t' || *linebuf == '\n')
			continue;

	lblprocstring:
		//屁股后边若有换行,回车,空格等都截取掉
		if (strlen(linebuf) > 0)
		{
			if (linebuf[strlen(linebuf) - 1] == 10 || linebuf[strlen(linebuf) - 1] == 13 || linebuf[strlen(linebuf) - 1] == 32)
			{
				linebuf[strlen(linebuf) - 1] = 0;
				goto lblprocstring;
			}
		}
		if (linebuf[0] == 0)
			continue;
		if (*linebuf == '[') //[开头的也不处理
			continue;

		//这种 “ListenPort = 5678”走下来;
		// = 5678
		//printf("!!!! %s\n", linebuf);
		char* ptmp = strchr(linebuf, '=');
		if (ptmp != NULL)
		{
			LPCConfItem p_confitem = new CConfItem;                    //注意前边类型带LP,后边new这里的类型不带
			memset(p_confitem, 0, sizeof(CConfItem));
			strncpy(p_confitem->ItemName, linebuf, (int)(ptmp - linebuf)); //等号左侧的拷贝到p_confitem->ItemName
			strcpy(p_confitem->ItemContent, ptmp + 1);                    //等号右侧的拷贝到p_confitem->ItemContent

			Ltrim(p_confitem->ItemName);
			Rtrim(p_confitem->ItemName);

			Ltrim(p_confitem->ItemContent);
			Rtrim(p_confitem->ItemContent);

			printf("itemname=%s | itemcontent=%s\n",p_confitem->ItemName,p_confitem->ItemContent);            
			m_ConfigItemList.push_back(p_confitem);  //内存要释放,因为这里是new出来的 
		} //end if
	} //end while(!feof(fp)) 

	fclose(fp); //这步不可忘记
	return true;
}
//根据ItemName获取配置信息字符串,不修改不用互斥
const char* CConfig::GetString(const char* p_itemname)
{
	std::vector<LPCConfItem>::iterator pos;
	for (pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos)
	{
		if (strcmp((*pos)->ItemName, p_itemname) == 0)
			return (*pos)->ItemContent;
	}//end for
	return NULL;
}

int CConfig::GetIntDefault(const char* p_itemname, const int def)
{
	std::vector<LPCConfItem>::iterator pos;
	for (pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos)
	{
		if (strcmp((*pos)->ItemName, p_itemname) == 0)
			return atoi((*pos)->ItemContent);
	}//end for
	return def;
}


int main()
{
	// 检测是否有内存泄漏
	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);

	CConfig* p_config = CConfig::GetInstance(); //单例类
	p_config->Load("conf.txt");
	printf("%s\n", p_config->GetString("Sock_WaitTimeEnable"));
	printf("%d\n", p_config->GetIntDefault("Sock_WaitTimeEnable",12));
	return 0;
}
  • 配置文件
  • 在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DongGu.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值