Gflags学习笔记

简介

Gflags是一套命名行处理的开源库,支持C++和Python,这里我主要学习C++上的应用。与getopt相比,Gflags具有更好的灵活性,可以在任意位置定义flags。

使用步骤:

1

定义flag。flag的定义需要使用到gflags.h中的宏。gflags为用户提供了多种可以定义的flags类型,类型如下

宏语句flag类型
DEFINE_stringstring字符串类型
DEFINE_int3232位整型
DEFINE_int6464位整型
DEFINE_uint6464位无符号整型
DEFINE_double64位双浮点型
DEFINE_bool布尔类型

以string类型为例,一个完整的定义语句共包括三部分,分别是flag的名称,默认值和说明,其中说明是在用户使用–help时的描述内容。
需要注意的是,由于名称对应的是变量名,因此不用加双引号,而默认值与说明均为一段字符串,因此都要加双引号。

DEFINE_string(name, "minminwang", "please input your name")

2

flag的布局。一个flag只可以被定义一次,如果想要在其他文件中使用已经定义的flag,需要使用到另一个宏DECLARE。每一种类型的flag都有一个对应的DECLARE宏。

为了降低文件之间的相互依赖,Gflags的使用一般需要在一个.c文件中使用DEFINE宏定义相关的flag,然后在.h文件中使用DECLARE宏进行声明,这样每个include这一.h文件的地方都可以使用全部的flag。

DECLARE_string(name)

3

flag变量。每声明一个flag时都会生成一个与之对应的flag变量,可以直接通过FLAG_flag_name的方式来获取改变量,变量类型取决于声明时所使用的宏类型,可以像正常变量一样对其进行操作。例如通过上述语句,我们就得到了一个名为FLAG_name的flag变量。在其他文件中,使用DECLARE宏之后就可以使用该flag变量。DECLARE语句等效于extern FLAG_name但这样会形成一种隐式的依赖关系,不推荐使用。

4

flag验证器。Gflags允许为每个flag注册一个验证器,可以在每次获取flag值之后对其格式或内容就行校验。验证器的注册格式为DEFINE_validator(flag名称,&验证函数)。一个简单的验证月份的验证器的注册方式如下:

static bool validateMonth(const char* flagname, int32 month){
	if (month >= 1 && month <= 12) {
		return true;
	} else {
		printf("%d is not a %s!\n", (int)month, flagname);
		return false;
	}
}

DEFINE_int32(month, 1, "a month in a year");
DEFINE_validator(month, &validateMonth);

5

flag参数的初始化。在flag参数定义完成之后,需要在main函数中通过命令行的输入对其进行初始化,具体可以使用google:ParseCommandLineFlags函数完成。该函数的输入共有三个,分别为argc,argv和remove_flags。其中argc与argv均为main函数的输入值,对应的是命令行的输入,由于在google::ParseCommandLineFlags函数中需要对这些参数进行修改,因此使用指针传递。remove_flags是一个bool类型的变量,当remove_flags为true时,ParseCommandLineFlags函数会在argv中移除标识与参数,只保留命名行参数,并将argc的值相应减小;而当其值为false时,ParseCommandLineFlags会在argv中保留参数和标识,只是将其移动到命令行参数的前面,同时argc不变。

./sample.sh --name="minminwang" --age=18 "daydayup" // --name和--age均为标识,minminwang和18为对应的参数,daydayup为命令行参数。

static bool validateAge(const char* flagname, int32 age){
	if (age >=0 && age<=100) {
		return ture;
	} else {
		printf("Invalid %s: %d", flagname, (int)age);
		return false;
	}
}

DEFINE_stirng(name, "", "the name of user.");
DEFINE_int32(age, 0, "the age of user.");
DEFINE_validator(age, &vallidateAge);

main(int argc, char* argv){  // 此时argc=3,argv="--name=minminwang --age=18 daydayup"
	google::ParseCommandLineFlags(&argc, &argv, true);  // 之后argc=1, argv="daydayup"
}

6

通过命令行设置flag的值。

// 对于bool类型的flag共有四种方式
--sex
--sex=true
--nosex
--sex=false
// 对于其他类型的flag也有四种方式
--name="minminwang"
-name="minminwang"
--name "minminwang"
-name "minminwang"

7

特殊标识。

--help  显示文件中所有标识的完整帮助信息
--helpfull  和-help 一样,
--helpshort  只显示当前执行文件里的标志
--helpxml  以 xml 凡是打印,方便处理
--version  打印版本信息,由 google::SetVersionString()设定
--flagfile  -flagfile=f 从文件 f 中读取命令行参数
...

示例代码分析

#include <gflags/gflags.h>

DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing");
DEFINE_string(languages, "english,french,german", "comma-separated list of languages to offer in the 'lang' menu");

int main(int argc, char **argv) {
  google::ParseCommandLineFlags(&argc, &argv, true);

  cout << "argc=" << argc << endl;
  if (FLAGS_big_menu) {
    cout << "big menu is ture" << endl;
  } else {
    cout << "big menu is flase" << endl;
  }

  cout << "languages=" << FLAGS_languages << endl;
  return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值