conf.h
配置文件读取程序 conf.h
#ifndef CONF_H_INCLUDE__
#define CONF_H_INCLUDE__
#include <string>
#include <map>
#include <sstream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CONF_BLANK_SEP "\t\v\r\n "
class Conf {
public:
static std::string right_trim(std::string value, char *sep) {
size_t pos = value.find_last_not_of(CONF_BLANK_SEP);
if (pos!= std::string::npos)
value.erase(pos+1);
else
value.clear();
return value;
}
static std::string strip_comment(std::string const &str) {
std::string ret;
size_t start = 0, end = str.size();
while (1){
size_t pos = str.find('#', start);
if (pos == std::string::npos) {
ret+= str.substr(start, std::string::npos);
break;
}
if (pos+1 < end && str[pos+1] == '#') {
ret+= str.substr(start, pos - start +1);
start = pos+2;
continue;
}
ret+= str.substr(start, pos-start);
break;
}
return ret;
}
int read(char const *file) {
FILE *f = fopen(file, "r");
if (f == NULL) {
return -1;
}
char *line= NULL;
size_t size = 1024;
line = (char *)malloc(size);
ssize_t len = 0;
while ((len=getline(&line, &size , f)) > 0) {
parse_line(strip_comment(line));
}free(line);
fclose(f);
file_= file;
return 0;
}
int save(char const *file) {
FILE *f = fopen(file, "r");
if (f == NULL) {
return -1;
}
typeof(table_.begin()) it = table_.begin(), iend = table_.end();
for(; it!=iend; ++it) {
fprintf(f, "%s\t%s\n", it->first.c_str(), it->second.c_str());
}
fclose(f);
return 0;
}
void set(std::string const & name, std::string const & value) {
table_[name] = value;
}
template <typename T>
void set(std::string const & name, T const & value) {
std::ostringstream out;
out<<value;
table_[name] = out.str();
}
int parse_line(std::string const &line) {
char const*p =line.c_str();
char const *key_start = p+strspn(p, CONF_BLANK_SEP);
size_t key_len = strcspn(key_start, CONF_BLANK_SEP);
p=key_start+key_len;
char const *value_start = p+strspn(p, CONF_BLANK_SEP);
std::string key(key_start, key_len);
std::string value= right_trim(value_start, CONF_BLANK_SEP);
table_.insert(std::make_pair(key, value));
return 0;
}
std::string get(std::string const &name, std::string const def="") const {
std::string ret = def;
typeof(table_.begin()) it = table_.find(name);
if (it == table_.end()) {
return ret;
}
return it->second;
}
template <typename T>
T get(std::string const & name, T const &def = T()) const {
std::string value = this->get(name);
std::istringstream in(value, std::istringstream::in);
T ret=def;
in>>ret;
return ret;
}
std::map<std::string, std::string> table_;
std::string file_;
};
#include <vector>
#include <libgen.h>
inline
std::string get_conf_path(Conf &conf, char const *name)
{
std::vector<char> path(conf.file_.begin(), conf.file_.end());
path.push_back('\0');
std::string ret = dirname((char *)(&*path.begin()));
ret.append("/../");
ret.append(conf.get(name));
return ret;
}
#undef CONF_BLANK_SEP
#endif //CONF_H_INCLUDE__
配置文件格式:
log_level 3
debug 1 #0 关闭调试
log_file /data/log/my.log #日志文件
还支持注释(使用 #comment)