转自:https://blog.csdn.net/achelloworld/article/details/41959595#
gflags是google开源的一套命令行参数解析工具,支持C++和Python语言,其使用方法;
1. 定义参数
使用gflags需要包含头文件#include <gflags/gflags.h>。将需要的命令行参数使用gflags的宏:DEFINE_xxxxx(变量名,默认值,help-string) 定义在文件当中,定义的参数是全局的,gflags支持的参数类型有:
DEFINE_bool: boolean DEFINE_int32: 32-bit integer DEFINE_int64: 64-bit integer DEFINE_uint64: unsigned 64-bit integer DEFINE_double: double DEFINE_string: C++ string
定义方式如下:
DEFINE_bool(is,true,"Hello World"); DEFINE_string(str,"python","language");
DEFINE_* 宏的三个参数分别代表命令行参数名,参数默认值,参数的帮助信息.
gflags不支持列表,但是可以借助string类型实现,比如:
DEFINE_string(languages,"English, Chinese,Japanese","Select languages?");
2. 参数访问
参数被定义后,可以通过FLAGS_name来访问对应的命令行参数,比如:
printf("%s", FLAGS_str);
snprintf(language, MAX_LEN, "%s", FLAGS_languages.c_str());
if(FLAGS_languages.find("English")!=string::npos)
{
isEnglish();
return 0;
}
通过DEFINE定义的参数,要保证访问变量的文件和定义参数的文件是同一个文件或者是头文件包含关系,否则将会访问不到定义的参数。
在其他文件中使用定义的flags变量:有些时候需要在main之外的文件使用定义的flags变量,这时候可以使用宏定义DECLARE_xxx(变量名)声明一下(就和c++中全局变量的使用是一样的,extern一下一样)
DECLARE_bool: boolean DECLARE_int32: 32-bit integer DECLARE_int64: 64-bit integer DECLARE_uint64: unsigned 64-bit integer DECLARE_double: double DECLARE_string: C++ string
在gflags的doc中,推荐在对应的.h文件中进行DECLARE_xxx声明,需要使用的文件直接include就行了。
3. 参数检查
检验输入参数是否合法:gflags库支持定制自己的输入参数检查的函数,参数定义后,可以为参数注册一个检查函数,当从命令行指定参数或通过SetCommandLineOption()指定参数时,检查函数就会被调用,两个参数分别为命令行参数名,以及设置的参数值。
#include <iostream> #include <string.h> #include <string> #include <stdio.h> #include <gflags/gflags.h> using namespace std; using namespace google; static bool ValidatePort(const char *flagname, int32_t val) { if(val > 0 && val < 32768) return true;
printf("Invalid value for --%s:%d\n",flagname,(int)val); return false; } DEFINE_int32(port, 6379, "what is the port ?"); int main(int argc, char **argv) { ParseCommandLineFlags(&argc, &argv, true); bool isPort = RegisterFlagValidator(&FLAGS_port, &ValidatePort); return 0; }
建议在定义参数后,立即注册检查函数。RegisterFlagValidator()在检查函数注册成功时返回true; 如果参数已经注册了检查函数,或者检查函数类型不匹配,返回false。
4. 初始化参数
通过调用ParseCommandLineFlags(&argc, &argv, true)实现,最后一个参数如果为true,gflags会移除Parse过的参数,如果为false则会保留。可能会对参数顺序进行调整。
5. 在命令行指定参数
可以通过:--参数名=参数值 来指定。例如下面代码:
#include <iostream> #include <string.h> #include <string> #include <stdio.h> #include <gflags/gflags.h> using namespace std; using namespace google; static bool ValidatePort(const char *flagname, int32_t val) { if(val > 0 && val < 32768) return true; return false; } DEFINE_int32(port, 6379, "what is the port ?"); DEFINE_string(ip, "127.0.0.1", "My ip ?"); int main(int argc, char **argv) { ParseCommandLineFlags(&argc, &argv, true); bool isPort = RegisterFlagValidator(&FLAGS_port, &ValidatePort); int32_t Port = FLAGS_port; string Ip = FLAGS_ip; cout << Port << endl; cout << Ip << endl; return 0; }
参数可以通过下面方式指定,参数之间可以没有顺序。
6. 定制你自己的help信息与version信息
gflags里面已经定义了-h和--version,你可以通过以下方式定制它们的内容
version信息:使用google::SetVersionString设定,使用google::VersionString访问
help信息:使用google::SetUsageMessage设定,使用google::ProgramUsage访问
注意:google::SetUsageMessage和google::SetVersionString必须在google::ParseCommandLineFlags之前执行
7. 一些特殊的参数认识
--help
打印定义过的所有参数的帮助信息
--version
打印版本信息 通过google::SetVersionString()指定
--nodefok
但命令行中出现没有定义的参数时,并不退出(error-exit)
--fromenv
从环境变量读取参数值 --fromenv=foo,bar表明要从环境变量读取foo,bar两个参数的值。通过
export FLAGS_foo=xxx; export FLAGS_bar=yyy 程序就可读到foo,bar的值分别为xxx,yyy。
--tryfromenv
与--fromenv类似,当参数的没有在环境变量定义时,不退出(fatal-exit)
--flagfile
从文件读取参数值,--flagfile=my.conf表明要从my.conf文件读取参数的值。在配置文件中指定参
数值与在命令行方式类似,另外在flagfile里可进一步通过--flagfile来包含其他的文件。