目录

一.gflags 介绍

二.gflags安装

三.gflags使用

1.包含头文件

2.定义参数

3.访问参数

4.不同文件访问参数

5.初始化所有参数

6.运行参数设置

7.配置文件的使用

8.特殊参数标识

四.总结


一.gflags 介绍

        gflags 是 Google 开发的一个开源库,用于 C++ 应用程序中命令行参数的声明、定义和解析。gflags 库提供了一种简单的方式来添加、解析和文档化命令行标志(flags),使得程序可以根据不同的运行时配置进行调整。

它具有如下几个特点

  • 易于使用gflags 提供了一套简单直观的 API 来定义和解析命令行标志,使得开发者可以轻松地为应用程序添加新的参数;
  • 自动帮助和文档gflags 可以自动生成每个标志的帮助信息和文档,这有助于用户理解如何使用程序及其参数;
  • 类型安全gflags 支持多种数据类型的标志,包括布尔值、整数、字符串等,并且提供了类型检查和转换;
  • 多平台支持gflags 可以在多种操作系统上使用,包括 WindowsLinux macOS;
  • 可扩展性gflags 允许开发者自定义标志的注册和解析逻辑,提供了强大的扩展性。

官方文档:https://gflags.github.io/gflags/

代码仓库:https://github.com/gflags/gflags.git

二.gflags安装

直接命令安装:

sudo apt-get install libgflags-dev

源码安装:

# 下载源码
git clone https://github.com/gflags/gflags.git
# 切换目录
cd gflags/
mkdir build
cd build/
# 生成 Makefile
cmake ..
# 编译代码
make
# 安装
make install

        未报错则安装完毕。

三.gflags使用

1.包含头文件

        使用 gflags 库来定义/解析命令行参数必须包含如下头文件。

#include <gflags/gflags.h>

2.定义参数

        利用 gflag 提供的宏定义来定义参数。该宏的 3 个参数分别为命令行参数名,参数默认值,参数的帮助信息。

DEFINE_bool(reuse_addr, true, "是否开始网络地址重用选项");
DEFINE_int32(log_level, 1, "日志等级:1-DEBUG, 2-WARN, 3-ERROR");
DEFINE_string(log_file, "stdout", "日志输出位置设置,默认为标准输出");

gflags 支持定义多种类型的宏函数:

DEFINE_bool
DEFINE_int32
DEFINE_int64
DEFINE_uint64
DEFINE_double
DEFINE_string

3.访问参数

        我们可以在程序中通过 FLAGS_name 像正常变量一样访问标志参数。比如在上面的例子中,我们可以通过 FLAGS_big_menu FLAGS_languages 变量来访问命令行参数。

4.不同文件访问参数

        如果想再另外一个文件访问当前文件的参数,以参数 FLAGS_big_menu 为例,我们可以使用用宏 DECLARE_bool(big_menu)来声明引入这个参数。

        其实这个宏就相当于做了 extern FLAGS_big_menu, 定义外部链接属性。

5.初始化所有参数

        当我们定义好参数后,需要告诉可执行程序去处理解析命令行传入的参数,使得FLAGS_*变量能得到正确赋值。我们需要在 main 函数中,调用下面的函数来解决命令行传入的所有参数。

google::ParseCommandLineFlags(&argc, &argv, true);
  • argc argv 就是 main 的入口参数;
  • 第三个参数被称为 remove_flags。如果它为 true, 表示ParseCommandLineFlags 会从 argv 中移除标识和它们的参数,相应减少 argc 的值;如果它为 false,ParseCommandLineFlags 会保留 argc 不变,但将会重新调整它们的顺序,使得标识再前面。这里的说明比较晦涩,下面我在Linux上写代码进行输出来演示。

        首先是第三个参数设置为false,我在命令行对命令行参数进行设置,而不使用默认值,因为如果使用默认值的话,argc的值在第三个参数设置为true和false的情况下是一样的,就看不出区别。

代码如下:

#include <gflags/gflags.h>
#include <iostream>DEFINE_string(ip, "127.0.0.1", "这是服务器监听ip地址,格式:127.0.0.1");
DEFINE_int32(port, 8080, "这是服务器监听端口,格式:8080");
DEFINE_bool(enableDebug, true, "是否开启调试模式,格式:true/false");int main(int argc, char* argv[])
{google::ParseCommandLineFlags(&argc, &argv, false);std::cout << "argc的值是:" << argc << std::endl;std::cout << "FLAGS_作为前缀版本:" << std::endl;std::cout << FLAGS_ip << std::endl;std::cout << FLAGS_port << std::endl;std::cout << FLAGS_enableDebug << std::endl;std::cout << "argv数组进行访问的版本" << std::endl;for(int i = 0;i < argc;i++){std::cout << argv[i] << std::endl;}return 0;
}

shell命令:

./main --ip="47.235.41.48" --port=9090 --enableDebug=false

输出:

        可以看到,argv中包含了完整的命令行参数,包括可执行文件总共四个,下面我们看看第三个参数为true的情况。

代码只是将第三个参数设置为true,其它不变,输出如下:

        这时候argv中就只有可执行文件的命令行内容了,argc也相应的变成了1,。也就是说,设置为true的情况下将gflags自定义的命令行参数给删除了,argc也相应减少。设置为true是我个人经常使用和推荐的版本,因为访问gflags命令行参数时,我们直接使用“FLAGS_”作为前缀即可,这样不用自己进行字符串解析,非常的方便。 

6.运行参数设置

        gflags 为我们提供了多种命令行设置参数的方式。

string 和 int 设置参数

exec --log_file="./main.log"
exec -log_file="./main.log"
exec --log_file "./main.log"
exec -log_file "./main.log"

        int版本的设置则是不加双引号,其它没有什么不同。

bool 设置参数

exec --reuse_addr
exec --noreuse_addr
exec --reuse_addr=true
exec --reuse_addr=false

        上面命令行中没有声明true或者false的前两行的意思就是设置为true,简化了书写。

        另外有一点专门的说明,--单独使用将会终止标识的处理。比如在 exec -f1 1 -- -f2 2 中, f1 被认为是一个标识,但 f2 不会。

7.配置文件的使用

        配置文件的使用,其实就是为了让程序的运行参数配置更加标准化,不需要每次运行的时候都手动收入每个参数的数值,而是通过配置文件,一次编写,永久使用。

        需要注意的是,配置文件中选项名称必须与代码中定义的选项名称一致。

例子,配置文件main.conf

--ip="222.2.2.2"
--port=7777
--enableDebug=false

命令行

./main --flagfile=./main.conf

        这里需要用到--flagfile这个选项来指明配置文件的地址。

        输出时则输出配置文件中的内容。

8.特殊参数标识

        gflags 也默认为我们提供了几个特殊的标识。

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

四.总结

        以上就是gflags的使用,非常的简单,并且允许在程序各个地方进行命令行参数的定义,不止在main函数中,但有一个缺点,也就是在两个文件中定义了名字相同的命令行参数,并且这两个文件进行了链接,那么程序就会编译报错,这就要求我们开发人员要格外小心。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/88942.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/88942.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/88942.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python爬虫实战:研究XlsxWriter 库相关技术

1. 研究背景与意义 1.1 网络爬虫技术价值 网络爬虫作为数据采集的核心工具,在金融、医疗、教育等领域发挥关键作用。据 Statista 数据显示,2025 年全球大数据市场规模预计达 3250 亿美元,高效的数据获取能力成为企业核心竞争力。Python 以其 80% 的市场占有率成为爬虫开发首…

ThreadLocal内部结构深度解析(Ⅰ)

目录 使用ThreadLocal 例子 内部结构分析 源码解析 图示详解 ThreadLocal是Java中一个非常重要且常用的线程局部变量工具类&#xff0c;它使得每个线程可以独立地持有自己的变量副本&#xff0c;而不是共享变量&#xff0c;解决了多线程环境下变量共享的线程安全问题。下面我…

Python 数据挖掘之数据探索

在数据挖掘的流程中&#xff0c;数据探索是非常关键的第一步&#xff0c;它能帮助我们深入了解数据的特点&#xff0c;为后续的预处理和模型构建打下坚实的基础。我们主要围绕四个方面展开&#xff1a;数据对象与特征、数据统计描述、数据可视化以及相关性和相似性度量。一、数…

高并发点赞场景Synchronized、AtomicLong、LongAdder 和 LongAccumulator性能分析

在高并发点赞场景中&#xff0c;我们需要一个高效、线程安全的计数器来记录点赞数。synchronized、AtomicLong、LongAdder 和 LongAccumulator 都是 Java 中用于实现原子操作的类&#xff0c;但它们的性能在高并发下差异显著。性能主要取决于线程竞争程度&#xff1a;竞争越高&…

postgreSQL的sql语句

目录 一&#xff1a;前提准备1.postgreSQL的安装可以参考我下面一片文章&#xff1a; 二&#xff1a;SQL语句 1.相同点&#xff1a;支持标准sql类型 2.参考详细学习地址&#xff1a; 3.postgresql与mysql的不同点 一&#xff1a;前提准备 1.postgreSQL的安装可以参考我下面…

vue3 JavaScript 数据累加 reduce

在Vue 3中&#xff0c;你可以使用JavaScript的reduce方法来处理数据累加。reduce方法通常用在数组上&#xff0c;它将数组中的每个元素通过一个累加器函数&#xff08;accumulator&#xff09;从左到右累积&#xff0c;最终生成一个单一的值。这在计算总和、累加值等场景中非常…

史上最清楚!读者,写者问题(操作系统os)

读者-写者问题是另一个里程碑式的同步互斥问题。它比生产者-消费者更复杂&#xff0c;因为它引入了不对称的访问权限&#xff1a;读者和读者之间是共享的&#xff0c;但写者和任何人&#xff08;包括读者和其他写者&#xff09;之间都是互斥的。我们用一个生动的比喻来解析这个…

使用Starrocks替换Clickhouse的理由

背景 Starrocks和clickhouse都是非常优秀的OLAP数据库&#xff0c;那么什么情况下使用clickhouse&#xff0c;什么场景下使用starrocks呢&#xff0c;本文就简单列举一下他们的优缺点 理由 首先两者都是列存储&#xff0c;并且都实现了列压缩&#xff0c;所以从存储中两者的压缩…

Mybatis 两级缓存可能导致的问题

Mybatis 两级缓存可能导致的问题两级缓存简介一级缓存 localCache效果开关二级缓存两级缓存可能导致的问题分布式环境下查询到过期数据事务隔离级别失效读已提交失效读未提交失效总结两级缓存简介 一级缓存 localCache 效果 一级缓存是 session 或者说事务级别的&#xff0c…

vue3+uniapp 使用vue-plugin-hiprint中实现打印效果

前言&#xff1a; vue3uniapp 使用vue-plugin-hiprint中实现打印效果 官网地址&#xff1a;gitee https://gitee.com/ccsimple/vue-plugin-hiprinthttps://gitee.com/ccsimple/vue-plugin-hiprint 实现效果&#xff1a; 预览打印内容&#xff1a; 实现步骤&#xff1a; 1、安…

【elementUI踩坑记录】解决 el-table 固定列 el-table__fixed 导致部分滚动条无法拖动的问题

目录一、问题背景二、 问题现象三、核心原因四、解决办法增强方案&#x1f680;写在最后一、问题背景 在使用 Element UI 的 el-table 组件时&#xff0c;固定列功能虽然实用&#xff0c;但会引发滚动条交互问题&#xff1a; 固定列区域悬浮显示滚动条但无法正常拖动滚动条 …

【机器人编程基础】python文件的打开和关闭

文件的打开和关闭 在Python中,文件操作是一项基本而重要的任务,涉及到打开、读取、写入、关闭文件等操作。正确地管理文件对于数据持久化、输入输出处理等至关重要。下面将详细解释如何在Python中打开和关闭文件,并提供相应的代码示例。 文件打开 在Python中,可以使用内…

ShenYu实战、问题记录

概述 一款高性能的国产的Apache开源API网关&#xff0c;官方文档。 在ShenYu v2.6.1, ShenYu注册中心只支持http类型&#xff0c;中间件注册类型已经被移除。 所以&#xff0c;请使用http注册类型来注册你的服务。不是微服务注册中心&#xff0c;它只是将元数据、选择器数据、…

走近科学IT版:EasyTire设置了ip,但是一闪之后就变回到原来的dhcp获得的地址

EasyTier 是一款简单、安全、去中心化的内网穿透和异地组网工具&#xff0c;适合远程办公、异地访问、游戏加速等多种场景。无需公网 IP&#xff0c;无需复杂配置&#xff0c;轻松实现不同地点设备间的安全互联。 上次实践的记录&#xff1a;适合远程办公、异地访问的EasyTier…

rk3588平台USB 3.0 -OAK深度相机适配方法

目录 文件更改记录表 1、usb规则添加 2、拉取相关依赖 3、安装python3、安装pip 4、安装依赖 5、安装ffmeg 6、摄像头功能测试 7、将视频拷贝到U盘查看 1、usb规则添加 由于OAK是USB设备,因此为了在使用 udev 工具的系统上与之通信, 您需要添加udev规则以使…

工厂模式总结

工厂模式1. 简单工厂模式&#xff08;Simple Factory&#xff09; 核心思想 定义一个工厂类&#xff0c;根据输入参数创建不同的具体对象。客户端不直接调用具体类的构造函数&#xff0c;而是通过工厂类获取对象。 示例代码 #include <iostream> #include <memory>…

MySQL的三种安装方式(mis、zip、yum)

目录 2.0数据库安装 2.1windows上.mis格式 环境准备 MySQL的安装 环境配置&#xff08;非必要&#xff09; 2.2windows上.zip格式安装 环境准备 配置文件的内容 MySQL的安装 附录可能出现问题 图形工具远程连接数据库 2.3Linux上安装yum包 环境准备 过程命令 My…

串口学习和蓝牙通信HC05(第八天)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-削好皮的Pineapple! &#x1f468;‍&#x1f4bb; hello 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 削好皮的Pineapple! 原创 &#x1f468;‍&#x1f4b…

设计总监的“轻量化”新武器:用Adobe Express,音频一键驱动动画

在快节奏的创意项目中&#xff0c;如何将复杂的设计理念或冗长的研究报告&#xff0c;快速转化为易于理解、富有吸引力的动态内容&#xff0c;是衡量一个团队沟通效率的关键。作为一名在海外设计界工作了十余年的设计师&#xff0c;我发现&#xff0c;最高效的团队&#xff0c;…

零知开源——STM32F407VET6驱动SHT41温湿度传感器完整教程

✔零知开源是一个真正属于国人自己的开源软硬件平台&#xff0c;在开发效率上超越了Arduino平台并且更加容易上手&#xff0c;大大降低了开发难度。零知开源在软件方面提供了完整的学习教程和丰富示例代码&#xff0c;让不懂程序的工程师也能非常轻而易举的搭建电路来创作产品&…