c++轮子---配置文件的读取

配置文件的读取
  • 使用配置文件,我们的服务器程序有了极大的灵活性;
  • 配置文件:文本文件,里面除了注释外不要使用中文(仅使用字母、数字、下划线);
  • 以#开头的行作为注释行
  • 项目的首要任务是将配置文件中的配置项读到内存中
//readconf.h
#pragma once

#include <vector>

typedef struct
{
	char ItemName[50];
	char ItemContent[500];
}CConfItem, *LPCConfItem; //用于存放配置文件里的字符和数字

class CConfig //单例类
{
private:
	CConfig();
public:
	~CConfig();
	static CConfig* m_instance;
public:
	static CConfig* GetInstance()
	{
		if (m_instance == NULL)
		{
			//lock
			m_instance = new CConfig();
			static CGrecycle cg; //用于释放对象
			//unlock
		}
		return m_instance;
	}

	class CGrecycle
	{
	public:
		~CGrecycle()
		{
			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; //存储配置信息的列表

};
//readconf.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>

#include "readconf.h"

static CConfig* m_instance = NULL;


CConfig::CConfig()
{

}

CConfig::~CConfig()
{
	std::vector<LPCConfItem>::iterator pos;
	for (pos = m_ConfigItemList.begin(); pos != m_ConfigItemList.end(); ++pos)
	{
		delete(*pos);
	}
	m_ConfigItemList.clear();
}

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

	while (!feof(fp))
	{
		if (fgets(linebuf, 500, fp) == NULL) //读取一行数据村日linebuf中
			continue;
		if (linebuf[0] == 0) 
			continue;
		//处理注释行
		if (*linebuf == ';' || *linebuf == ' ' || *linebuf == '#' || *linebuf == '\t' || *linebuf == '\n')
			continue;
			
		//尾部若有换行,回车,空格等都截取掉
	JumpToHere:
		if (linebuf[strlen(linebuf) - 1] == 10 || linebuf[strlen(linebuf) - 1] == 13 || linebuf[strlen(linebuf) - 1] == 32)
		{
			linebuf[strlen(linebuf) - 1] = 0;
			goto JumpToHere;
		}
		if (linebuf[0] == 0)
			continue;
		if (*linebuf == '[') //[开头的也不处理
			continue;
		char* ptemp = strchr(linebuf, '=');
		if (ptemp != NULL)
		{
			LPCConfItem p_ConfItem = new CConfItem();
			memset(p_ConfItem, 0, sizeof(CConfItem));
			strncpy(p_ConfItem->ItemName, linebuf, (int)(ptemp - linebuf));
			strcpy(p_ConfItem->ItemContent, ptemp + 1);

			Rtrim(p_ConfItem->ItemName);
			Ltrim(p_ConfItem->ItemName);
			Rtrim(p_ConfItem->ItemContent);
			Ltrim(p_ConfItem->ItemContent); //截取首尾空格

			m_ConfigItemList.push_back(p_ConfItem); //回收动态空间
		}
	
	}
	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 (stricmp((*pos)->ItemContent, p_itemname) == 0) //linux: strcasecmp()
		{
			return (*pos)->ItemContent;
		}
	}
	return NULL;
}

//根据ItemName获取数字类型配置信息
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 (stricmp((*pos)->ItemContent, p_itemname) == 0) //linux: strcasecmp()
		{
			return atoi((*pos)->ItemContent);
		}
	}
	return def;
}
void Rtrim(char* string) //清除尾部空格
{
	if (string = NULL) return;
	size_t len = 0;
	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;
}
  • 这样在main函数中,我们就可以方便地将配置文件载入内存:
int main(int argc, char* const *argv)
{
	CConfig* p_config = CConfig::GetInstance();
	if (p_config->Load("nginx.conf") == false) //把配置文件内容载入到内存
	{
		printf("配置文件载入失败,退出!\n");
		exit(1);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值