应用程序往往都有一个配置文件,在windows下,一般采用*.ini文件的方式,我们需要调用windows api来读取配置文件,api使用起来繁琐,笔者自己开发了一个读配置文件的类,使用十分方便,在使用的时候只需要实现具体的一个虚函数即可。
#pragma once
#include "string"
#include "iostream"
using namespace std;
#define BLANK 32
class CFiletovariable
{
public:
CFiletovariable(void);
CFiletovariable(string filename);
~CFiletovariable(void);
private:
string filename;
public:
void readcfg();
private:
long getfilesize();
void process(string & buff);
void subprocess(string & buff);
void trimspace(string & buff);
void deletecomment(string & buff);
void deleteblankrow(string & buff);
int countpart(string sour, string part[], char flag);
protected:
virtual void insert(string section, string key, string value);
};
#include "Filetovariable.h"
CFiletovariable::CFiletovariable(void)
{
}
CFiletovariable::CFiletovariable(string filename)
{
this->filename = filename;
}
CFiletovariable::~CFiletovariable(void)
{
}
void CFiletovariable::readcfg()
{
long size = getfilesize();
FILE *fp = NULL;
int err = fopen_s(&fp, filename.c_str(), "rt");
if (err != 0)
{
cout<<"file is not existed, please check where the configuration file is"<<endl;
return;
}
char *pbuff = new char[size];
memset(pbuff, 0, size);
fread(pbuff, size, 1, fp);
string content(pbuff);
delete []pbuff;
process(content);
fclose(fp);
}
long CFiletovariable::getfilesize()
{
long size = 0;
FILE *fp = NULL;
int err = fopen_s(&fp, filename.c_str(), "rt");
if (err != 0)
{
cout<<"file is not existed, please check where the configuration file is"<<endl;
return size;
}
fseek(fp, 0, SEEK_END);
size = ftell(fp);
fclose(fp);
return size;
}
void CFiletovariable::trimspace(string & buff)
{
int pos = buff.find(BLANK, 0);
while(pos != string::npos)
{
buff.erase(pos, 1);
pos = buff.find(BLANK, pos);
}
}
void CFiletovariable::deletecomment(string & buff)
{
int pos1 = buff.find(';', 0);
while(pos1 != string::npos)
{
int pos2 = buff.find('\n\r', pos1 + 1);
buff.erase(pos1, pos2 - pos1 + 1);
pos1 = buff.find(';', 0);
}
}
void CFiletovariable::deleteblankrow(string & buff)
{
int pos1 = buff.find('\n\r', 0);
while(pos1 != string::npos)
{
int pos2 = buff.find('\n\r', pos1 + 1);
if (pos2 - pos1 == 1)
{
buff.erase(pos1, pos2 - pos1);
}
pos1 = buff.find('\n\r', pos2);
}
}
void CFiletovariable::process(string & buff)
{
string section;
int count = 0;
trimspace(buff);
deletecomment(buff);
deleteblankrow(buff);
printf("%s\n", buff.c_str());
int pos1 = buff.find('[', 0);
int pos2 = buff.find('[', pos1 + 1);
while(pos2 != string::npos)
{
section = buff.substr(pos1, pos2 - pos1);
subprocess(section);
pos1 = pos2;
pos2 = buff.find('[', pos1 + 1);
}
section = buff.substr(pos1, buff.size() - pos1);
subprocess(section);
return;
}
void CFiletovariable::subprocess(string& buff)
{
int pos1 = buff.find('[', 0);
int pos2 = buff.find(']', 0);
string section = buff.substr(pos1 + 1, pos2 - pos1 - 1);
pos1 = buff.find('\n\r', 0);
pos2 = buff.find('\n\r', pos1 + 1);
while(pos2 != string::npos)
{
string keyandvalue = buff.substr(pos1 + 1, pos2 - pos1 - 1);
string part[2];
int count = countpart(keyandvalue, part, '=');
if (count == 2)
{
insert(section, part[0], part[1]);
}
pos1 = pos2;
pos2 = buff.find('\n\r', pos1 + 1);
}
}
int CFiletovariable::countpart(string sour, string part[], char flag)
{
int count = 0;
int pos1 = 0;
int pos2 = sour.find(flag, pos1);
while(pos2 != string::npos)
{
part[count] = sour.substr(pos1, pos2 - pos1);
pos1 = pos2 + 1;
pos2 = sour.find(flag, pos1);
count++;
}
part[count] = sour.substr(pos1, sour.length() - pos1);
count++;
return count;
}
void CFiletovariable::insert(string section, string key, string value)
{
}
下边是主函数测试:
// readcfg.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "filetovariable.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
CFiletovariable ftovari("D:\\C++\\readcfg\\Debug\\test.txt");
ftovari.readcfg();
system("pause");
return 0;
}