C++实现简单的配置文件读取器
在做游戏的时候,会经常为了适应不同的需求而对游戏某些功能的属性做出改变,特别是在做调试的时候,会为了改编游戏效果而改动很少的代码,但不得不重新编译一次源码,这样所耗费的时间是非常不值得的。因此,出现了配置文件这种东西,当我们对游戏内的功能做出改变,在重新启动游戏甚至是直接在游戏内就能看出变化就显得很香了。今天我们就来用C++实现以下如何去解析一个配置文件。
文件格式
一般配置文件都是“.cfg”,“.ini”,“.conf”之类的扩展名,而里面的文件内容也就是以节,键值对的形式存在,看起来非常简单。
从上图来看,简单的配置文件都会存在一个节(Seection),若干键值对(K-V),而一个节的作用域从本节开始,到下一个节开头或文件尾。
结构设计
在我们了解过配置文件的结构之后,就可以针对其设计出C++的数据结构了,从上面来看很明显,我们使用Map容器来保存其数据,这也是最合适的数据结构了。而对其操作我给了以下步骤:
- Reader读取一个配置文件,这一步主要将配置文件读取到Root结构中,他只负责将文件内容添加到Root对象中。
- Root负责将Reader传来的数据保存到自己的结构中,以便Value对象的读取,一个Root对象就是一个配置文件。
- Value负责获取Root对象中的属性,可以有若干个Value来访问同一个Root对象。同时Value对象负责将Root对象的数据转换成不同的数值。
废话不多书,我们直接开整!
首先就是Root类,作为连接文件和最终数值的存在,将其放在第一位,而其结构也是直接使用了STL的map容器:std::map< sdt::string,std::mapstd::string,std::string >。
class Root {
public:
Root();
std::string ValueBy(std::string section, std::string key);
bool Add(std::string& section, std::string key,std::string val);
void Print(); //这个函数用来测试文件内容是否保存完整
private:
std::map< std::string, std::map< std::string, std::string > >mRoots;
};
然后就是文件读取了,他非常简单:
class Reader {
public:
static void Generate(const char* path,Root& root);
};
由于他只负责将文件内容塞到Root里面,那只需要一个静态函数就OK。
紧接着就是用来保存数值的Value对象了,也很简单:
class Value {
public:
explicit Value(Root& root,std::string section);
Value& operator[](std::string key);
int Int();
unsigned int Uint();
char Char();
float Float();
double Double();
std::string String();
bool Boolean();
private:
std::string mSection;
std::string mValue;
Root& mRoot;
};
这样我们就完成了解析的大半工程,剩下的就是实现上面的功能了,好家伙!原来如此简单!造他就完了嗷。
Configure.cpp
static void ClearComment(std::string& str)
{
size_t spos = str.find('#');
if