main函数:
#include <iostream>
#include "configfile.h"
using namespace std;
int main() {
ConfigFile cfg("test.cfg");
cout << "Dump:" << endl;
cfg.dump();
cout << endl;
cout << cfg.getvalue<string>("who") << endl;
cout << cfg.getvalue<float>("number") << endl;
cout << cfg.getvalue<int>("number") << endl;
cout << cfg.getvalue<int>("notThere") << endl;
cout << cfg.getvalue<int>("notThere", -1) << endl;
cout << cfg.getvalueidx<int>("array", 2, -1) << endl;
getchar();
return 0;
}
config.h
#ifndef CONFIGFILE_H
#define CONFIGFILE_H
#include <string>
#include <list>
#include <map>
#include <sstream>
#include <iostream>
class ConfigFile {
public:
ConfigFile(std::string filename);
ConfigFile();
bool load(std::string filename);
~ConfigFile();
void dump(void);
template < typename T>
T getvalue(std::string key) {
std::string str = datamap[key];
if (str=="") {
std::cerr << "WARNING: '" << key <<"' was not defined in " << filename << "! Value is undefined!" << std::endl;
}
std::stringstream ss;
ss << str;
T value;
ss >> value;
return value;
}
template < typename T>
T getvalue(std::string key, T defaultValue) {
std::string str = datamap[key];
if (str=="") {
return defaultValue;
}
return getvalue<T>(key);
}
template < typename T>
T getvalueidx(std::string key,int idx, T defaultValue) {
std::stringstream ss;
ss << idx;
std::string query=key+std::string("[")+ss.str()+std::string("]");
return getvalue<T>(query,defaultValue);
}
template < typename T>
T getvalueidx(std::string key,int idx) {
std::stringstream ss;
ss << idx;
std::string query=key+std::string("[")+ss.str()+std::string("]");
return getvalue<T>(query);
}
private:
std::map<std::string,std::string> datamap;
std::string filename;
};
#endif
config.cpp
#include "configfile.h"
#include <fstream>
using namespace std;
void str2lower(string &str) {
for(unsigned int i=0;i<str.size();i++)
{
str[i] = tolower(str[i]);
}
}
std::string trim(std::string const& source, char const* delims = " \t\r\n") {
std::string result(source);
std::string::size_type index = result.find_last_not_of(delims);
if(index != std::string::npos)
result.erase(++index);
index = result.find_first_not_of(delims);
if(index != std::string::npos)
result.erase(0, index);
else
result.erase();
return result;
}
ConfigFile::ConfigFile() { }
ConfigFile::ConfigFile(string filename) {
if(!load(filename))
cerr << "Configfile '" << filename << "' not found!" << endl;
}
bool ConfigFile::load(string filename) {
this->filename=filename;
fstream f;
f.open(filename.c_str(),fstream::in);
if (!f.is_open()) {
return false;
}
string line;
int lnr=-1;
while (getline(f,line)) {
lnr++;
//Skip Comments and empty lines
if (! line.length()) continue;
if (line[0] == '#') continue;
if (line[0] == ';') continue;
int posTrenner=line.find('=');
if (posTrenner==-1)
posTrenner=line.find(' ');
if (posTrenner==-1) {
cerr << "WARNING: Statement '" << line << "' in file "<< filename << ":"<<lnr<<" is invalid and therefor will be ignored" << endl;
continue;
}
string key=trim(line.substr(0,posTrenner));
string value=trim(line.substr(posTrenner+1));
//Case insensitive
str2lower(key);
if (datamap[key]!="") {
cerr << "WARNING: Statement '" << line << "' in file "<< filename << ":"<<lnr<<" redefines a value!" << endl;
}
datamap[key]=value;
}
f.close();
return true;
}
void ConfigFile::dump(void) {
for (map<string,string>::iterator iter= datamap.begin(); iter!=datamap.end();iter++){
cout << "key: '" << iter->first <<"' \t value: '"<< iter->second <<"'"<<endl;
}
}
ConfigFile::~ConfigFile() {
}
参考:
benreh/configfile: A very simple reader for config files written in C++ (github.com)