152 Linux C++ 通讯架构实战7 ,makefile编写改成for cpp,读配置文件,内存泄漏查找,设置标题实战

读写配置文件代码实战。nginx.conf

一个项目要启动,需要配置很多信息,第一项就是学习如何配置一个项目

nginx.conf的内容

#是注释行,
#每个有效配置项用 等号 处理,等号前不超过40个字符,等号后不超过400个字符;

 
#[开头的表示组信息,也等价于注释行
[Socket]
ListenPort = 5678    

DBInfo = 127.0.0.1;1234;myr;123456;mxdb_g

我们的目的是:

1.将 ListenPort的值取出来

2.将DBInfo的值取出来

ngx_c_conf.h


#ifndef __NGX_CONF_H__
#define __NGX_CONF_H__

#include <vector>

#include "ngx_global.h"  //一些全局/通用定义

//类名可以遵照一定的命名规则规范,比如老师这里,第一个字母是C,后续的单词首字母大写
class CConfig
{
//---------------------------------------------------
//这段代码老师在《c++从入门到精通》 多线程这章老师提过 单例设计模式,就是如下这些代码,大家即便没学过,也可以现在学
private:
	CConfig();
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; //存储配置信息的列表

};

#endif

ngx_c_conf.cxx


//系统头文件放上边
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <vector>

//自定义头文件放下边,因为g++中用了-I参数,所以这里用<>也可以
#include "ngx_func.h"     //函数声明
#include "ngx_c_conf.h"   //和配置文件处理相关的类,名字带c_表示和类有关

//静态成员赋值
CConfig *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);
	}//end for
	m_ConfigItemList.clear(); 
}

//装载配置文件
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;

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

        //处理注释行 
        if(*linebuf==';' || *linebuf==' ' || *linebuf=='#' || *linebuf=='\t'|| *linebuf=='\n')
			continue;
        
    lblprocstring:
        //屁股后边若有换行,回车,空格等都截取掉
		if(strlen(linebuf) > 0)
		{
            //10 换行,13回车,32 是空格
			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”走下来;
        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

            Rtrim(p_confitem->ItemName);
			Ltrim(p_confitem->ItemName);
			Rtrim(p_confitem->ItemContent);
			Ltrim(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(strcasecmp( (*pos)->ItemName,p_itemname) == 0)
			return (*pos)->ItemContent;
	}//end for
	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(strcasecmp( (*pos)->ItemName,p_itemname) == 0)
			return atoi((*pos)->ItemContent);
	}//end for
	return def;
}



nginx.cxx



#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include "ngx_c_conf.h"  //和配置文件处理相关的类,名字带c_表示和类有关
#include "ngx_signal.h"
#include "ngx_func.h"    //各种函数声明

//和设置标题有关的全局量
char **g_os_ar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值