大家好,我是 DongGu ,是一名软件工程专业大二的学生,写博客一方面是为了记录自己的学习过程,把自己犯的错误进行分享。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!有任何问题可以评论 或者 ___>
QQ联系(1521839703)
C++ 读配置文件
- 关键定义好配置文件的格式
- 再按规则提取配置项, 和配置属性
#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;
}
- 配置文件