国外的一些网站百度百科合作模式
LIB-ZC, 一个跨平台(Linux)平台通用C/C++扩展库,命令行参数和配置文件
- 本库 打通了命令行参数和配置文件.
- 推荐但不强制使用
命令行
命令行参数, 风格/例子
./cmd -name1 val1 arg1 -name2 val2 --bool1 --bool2 arg2 arg3
- 1个横杠 - 开始的是"参数名", 后面必须跟一个"参数值"
- 2个横杠 – 开始的是布尔型的参数, 后面没有"参数值", (逻辑上)值为真
- 其他参数为普通参数
命令行方法
// 命名空间 zcc::main_argument// 默认全局配置
extern zcc::config var_main_config;struct option
{const char *key;const char *val;
};// main 函数入口的 argc
extern int var_argc;
// main 函数入口的 argv
extern char **var_argv;
// 命令行参数的 key/value 对
extern std::vector<option> var_options;
// 命令行的参数
extern std::vector<const char *> var_parameters;
// var_parameters.size()
extern int var_parameter_argc;
// (char **)(var_parameters.c_str())
extern char **var_parameter_argv;
// 解析命令行
void run(int argc, char **argv, bool cmd_mode = true);
执行逻辑
已知:
./cmd -name1 val1 arg1 -name2 val2 --bool1 --bool2 arg2 arg3
调用函数
zcc::main_argument::run(argc, argv);
有如下效果:
系统会初始化全局配置变量
var_argc = argc;
var_argv = argv;
progname = argv[0];
而且逻辑上:
// var_main_config
zcc::var_main_config[name1] = val1
zcc::var_main_config[name2] = val2
zcc::var_main_config[bool1] = "yes"
zcc::var_main_config[bool2] = "yes"// var_options
var_options = {{name1, val1}, {name2, val2}, {boo1, yes}, {bool2, yes}}// var_parameters
var_parameters = {arg1, arg2, arg3}
另外
- 如果参数中出现(可以多组) -config somepath.cf, 那么会立即加载配置文件somepath.cf到 zcc::var_main_config
- 遵循规则: 后加载的配置项覆盖先加载的配置项
- 遵循规则: 命令行上的配置项覆盖配置文件中的配置项
配置
先看一个配置文件例子,内容如下
# 忽略空行# 行首第一个非空字符是#, 则忽略本行#
# 每配置行以 "=" 为分隔符
# 配置项和配置值都需要过滤掉两侧的空白
# 不支持任何转义
server-command = bin/milter
server-log = syslog,mail# 相同配置项, 以后一个为准
spamd_server = var/socket/spamd
spamd_server = var/socket/spamd222
config 类
// 线程, 读写不安全
// 线程, 只有读是安全的
class config : public std::map<std::string, std::string>
{
public:config();~config();config &reset();virtual inline void afterUpdate() {};config &update(const char *key, const char *val, int vlen = -1);config &update(const char *key, const std::string &val);config &update(const std::string &key, const std::string &val);config &remove(const char *key);config &remove(const std::string &key);// 从文件加载配置, 且覆盖bool load_from_file(const char *pathname);bool load_from_file(const std::string &pathname){return load_from_file(pathname.c_str());}// 从另一个配置复制config &load_another(config &another);config &debug_show();// 获取值std::string *get_value(const char *key);std::string *get_value(const std::string &key);const char *get_cstring(const char *key, const char *def_val = "");const char *get_cstring(const std::string &key, const char *def_val = "");std::string get_string(const char *key, const char *def_val = "");std::string get_string(const std::string &key, const char *def_val = "");const std::string &get_string(const std::string &key, const std::string &def_val);// 获取布尔值, y/Y/t/T/1 => true, n/N/f/F/0 => falsebool get_bool(const char *key, bool def_val = false);bool get_bool(const std::string &key, bool def_val = false);// atoiint get_int(const char *key, int def_val = 0);int get_int(const std::string &key, int def_val = 0);// atolint64_t get_long(const char *key, int64_t def_val = 0);int64_t get_long(const std::string &key, int64_t def_val = 0);// 获取时间秒值 1s, 1m, 1h, 1d, 1wint64_t get_second(const char *key, int64_t def_val = 0);int64_t get_second(const std::string &key, int64_t def_val = 0);// 获取大小字节 1b, 1k, 1m, 1gint64_t get_size(const char *key, int64_t def_val = 0);int64_t get_size(const std::string &key, int64_t def_val = 0);private:void *unused_;
};