gflags-命令行参数库超详细使用教程

发布时间:2026/7/19 9:21:56
gflags-命令行参数库超详细使用教程 一、gflags是什么gflags是Google开源的一个C库专门用来处理命令行参数的声明、定义和解析。简单来说就是帮你管理程序启动时的那些配置参数的。它有这么几个厉害的特点简单好用一套宏定义直接搞定API非常直观自动生成帮助文档不用自己写–help的输出gflags自动帮你生成类型安全支持bool、int、string等多种类型自带类型检查跨平台Windows、Linux、macOS都能用扩展性强可以自定义注册和解析逻辑官方文档https://gflags.github.io/gflags/代码仓库https://github.com/gflags/gflags.git二、gflags安装方法一命令一键安装Ubuntu下一条命令搞定sudoapt-getinstalllibgflags-dev方法二源码安装追求最新版# 下载源码gitclone https://github.com/gflags/gflags.git# 切换目录cdgflags/mkdirbuildcdbuild/# 生成Makefilecmake..# 编译代码make# 安装sudomakeinstall此方法比较复杂也比较古老新手建议方法一哦安装完成后你会在系统里看到libgflags.a静态库和gflags.h等头文件就说明安装成功啦三、gflags基础使用1. 包含头文件使用gflags必须包含这个头文件记住了#includegflags/gflags.h编译的时候别忘了链接库g main.cc-omain-lgflags2. 定义命令行参数gflags用宏来定义参数三个参数分别是参数名、默认值、帮助说明。// 布尔类型参数DEFINE_bool(reuse_addr,true,是否开启网络地址重用选项);// 32位整数参数DEFINE_int32(log_level,1,日志等级:1-DEBUG, 2-WARN, 3-ERROR);// 字符串参数DEFINE_string(log_file,stdout,日志输出位置设置默认为标准输出);gflags支持的参数类型宏有这6种DEFINE_bool—— 布尔类型DEFINE_int32—— 32位整数DEFINE_int64—— 64位整数DEFINE_uint64—— 64位无符号整数DEFINE_double—— 浮点数DEFINE_string—— 字符串3. 访问参数定义好之后怎么用呢直接通过FLAGS_参数名就能像普通变量一样访问也就是在定义的参数前面直接加一个FLAGS_比如上面定义的reuse_addr就用FLAGS_reuse_addr来访问是不是很简单std::coutFLAGS_log_levelstd::endl;// 输出日志等级std::coutFLAGS_log_filestd::endl;// 输出日志文件路径4. 初始化解析参数光定义还不行得告诉程序去解析命令行传进来的参数。在main函数开头调用这个函数intmain(intargc,char*argv[]){google::ParseCommandLineFlags(argc,argv,true);// 后面就可以正常使用FLAGS_xxx了return0;}这里来拆分理解一下三个参数argc和argv就是main函数入口的那俩参数第三个参数叫remove_flags为true时解析完会把识别到的flag参数从argv里删掉argc也对应减少解析前argc5argv [./server, --port8080, --log_filelog.txt, test1, test2]remove_flagstrue 解析后argc3argv [./server, test1, test2]所有配置 flag 全部清除只剩业务参数 test1 test2。为false时保留所有参数但会调整顺序把flag参数放前面同样上面命令解析后argc 仍 5argv [./server, --port8080, --log_filelog.txt, test1, test2]只是不管输入顺序多乱flag 都会全部前置。四、gflags进阶玩法1. 跨文件访问参数如果参数定义在a.cc里我在b.cc想用怎么办用DECLARE宏声明一下就行// 在b.cc中声明引入a.cc里定义的reuse_addr参数DECLARE_bool(reuse_addr);其实这个宏本质就是做了个extern声明赋予外部链接属性跟我们平时写的extern变量一个道理~2. 命令行传参的多种姿势gflags支持好几种传参写法都能用看你习惯哪种string和int类型./main--log_file./main.log./main-log_file./main.log./main--log_file./main.log./main-log_file./main.log等号或者空格分隔都行单横杠双横杠也行非常灵活。bool类型./main--reuse_addr# 设为true./main--noreuse_addr# 设为false前面加no./main--reuse_addrtrue# 显式设为true./main--reuse_addrfalse# 显式设为false还有个小知识点遇到--就会停止参数解析。比如./main -f1 1 -- -f2 2只有f1被识别f2不算。3. 配置文件方式传参参数多了每次手敲太麻烦可以写进配置文件里配置文件main.conf长这样-reuse_addrtrue -log_level3 -log_file./log/main.log⚠️ 注意配置文件里字符串不用加双引号参数名要和代码里定义的一致运行的时候指定配置文件./main--flagfilemain.conf一键加载所有配置非常方便4. 自带的特殊参数gflags还贴心地给我们内置了几个实用参数--help# 显示所有标志的帮助信息--helpfull# 帮助信息更全面--helpshort# 只显示当前文件里的标志--helpxml# 以xml格式输出方便程序处理--version# 打印版本信息需要用SetVersionString设置--flagfilef# 从文件f读取参数直接./main --helpshort就能看到你定义的所有参数和说明再也不用手动写帮助文档啦五、完整入门案例光说不练假把式我们来写一个完整的小例子跑一跑。目录结构|-- main.cc |-- main.conf -- makefile配置文件 main.conf-reuse_addrtrue -log_level3 -log_file./log/main.log代码 main.cc#includegflags/gflags.h#includeiostream// 定义三个命令行参数DEFINE_bool(reuse_addr,true,是否开启网络地址重用选项);DEFINE_int32(log_level,1,日志等级:1-DEBUG, 2-WARN, 3-ERROR);DEFINE_string(log_file,stdout,日志输出位置设置默认为标准输出);intmain(intargc,char*argv[]){// 解析命令行参数google::ParseCommandLineFlags(argc,argv,true);// 打印参数值std::coutreuse: FLAGS_reuse_addrstd::endl;std::coutlevel: FLAGS_log_levelstd::endl;std::coutfile: FLAGS_log_filestd::endl;return0;}Makefilemain : main.cc g -stdc17 $^ -o $ -lgflags运行效果1. 查看帮助信息$ ./main-helpshortFlags from main.cc: log_file(日志输出位置设置默认为标准输出)type: string default:stdoutlog_level(日志等级:1-DEBUG,2-WARN,3-ERROR)type: int32 default:1reuse_addr(是否开启网络地址重用选项)type: bool default:true2. 默认运行使用默认值$ ./main reuse:1level:1file: stdout3. 通过配置文件运行$ ./main-flagfile./main.conf reuse:1level:3file: ./log/main.log4. 命令行直接传参$ ./main--noreuse_addr--log_level2--log_file./log reuse:0level:2file: ./log完美运行所有参数都正确解析了。总结gflags这个库用起来是不是超级方便总结一下核心步骤#include gflags/gflags.h包含头文件用DEFINE_xxx宏定义参数main里调用google::ParseCommandLineFlags解析通过FLAGS_xxx直接使用还有配置文件、跨文件声明、自动帮助文档这些实用功能日常开发完全够用了。以后写C程序需要传参数再也不用手写解析逻辑啦~是不是看的头都大了哈哈没事多敲两遍代码就熟了创作不易记得这次一定三连哈哈