【C++】gflag使用指南

news/2025/2/5 23:12:11/文章来源:https://www.cnblogs.com/o-O-oO/p/18700308

一、什么是gflags?

gflags 是一个用于定义命令行参数的 C++ 库,它由 Google 开发并开源。通过 gflags,你可以轻松地在你的程序中添加各种类型的命令行选项,包括整数、布尔值、字符串等,并且可以为这些选项设置默认值。此外,gflags 还提供了强大的帮助信息生成功能,使得用户更容易理解和使用你的程序。

二、安装gflags

在开始之前,请确保你的系统已经安装了 gflags。对于基于 Debian 的 Linux 发行版(如 Ubuntu),可以通过以下命令安装:

sudo apt-get install libgflags-dev

如果你使用的是 macOS,可以通过 Homebrew 来安装:

brew install gflags

github 源码链接:

https://github.com/gflags/gflags

三、如何在C++项目中引入gflags

首先,在 CMakeLists.txt 文件中添加对 gflags 的依赖。假设你正在使用的 CMake 版本至少是 3.10,那么你可以这样写:

find_package(gflags REQUIRED)
include_directories(${GFLAGS_INCLUDE_DIRS})
target_link_libraries(your_project ${GFLAGS_LIBRARIES})

这里的 your_project 需要替换为你实际项目的名称。

四、编写带有gflags支持的C++程序

下面是一个简单的例子,演示如何在一个 C++ 程序中使用 gflags 来定义和处理命令行参数。

示例代码

#include <gflags/gflags.h>
#include <iostream>// 定义标志变量
DEFINE_int32(port, 8080, "Server port to listen on.");
DEFINE_bool(verbose, false, "Print verbose logging information.");
DEFINE_string(config_file, "", "Path to the configuration file.");int main(int argc, char* argv[ ]) {// 解析命令行参数gflags::ParseCommandLineFlags(&argc, &argv, true);// 使用标志变量if (FLAGS_verbose) {std::cout << "Verbose mode is enabled." << std::endl;}std::cout << "Listening on port: " << FLAGS_port << std::endl;if (!FLAGS_config_file.empty()) {std::cout << "Using config file: " << FLAGS_config_file << std::endl;}return 0;
}

构建与运行

保存上面的代码到文件 main.cpp 中,并创建一个名为 CMakeLists.txt 的文件,内容如下:

cmake_minimum_required(VERSION 3.10)
project(GflagsExample)set(CMAKE_CXX_STANDARD 14)find_package(gflags REQUIRED)
include_directories(${GFLAGS_INCLUDE_DIRS})add_executable(GflagsExample main.cpp)
target_link_libraries(GflagsExample ${GFLAGS_LIBRARIES})

然后执行以下步骤来构建和运行程序:

mkdir build
cd build
cmake ..
make
./GflagsExample --help

这将显示所有可用的命令行选项及其描述。尝试运行以下命令查看不同选项的效果:

./GflagsExample --port=9090 --verbose --config_file=config.txt

五、gflag 的工作原理

gflags 是一个用于处理命令行参数的C++库,它简化了程序中命令行选项的定义、解析和使用过程。下面是的工作原理及如何在程序中调用它的详细解释:

5.1 定义标志

首先,应用程序定义一些标志(flags)。
这些标志可以是各种类型,如整型、浮点型、字符串等。通过宏定义来声明这些标志,例如:

DEFINE_bool:布尔类型的标志

DEFINE_int32 或 DEFINE_int64:整数类型的标志

DEFINE_double:双精度浮点数类型的标志

DEFINE_string:字符串类型的标志

每个宏接受四个参数:标志名、默认值、描述信息以及可选的标志名称列表。例如:

DEFINE_string(name, "world", "The name to greet");

这行代码定义了一个名为name的字符串标志,默认值为"world",并且提供了简短的帮助文本。

5.2 解析命令行参数

在主函数或其他适当的位置,调用gflags::ParseCommandLineFlags函数来解析传递给程序的所有命令行参数。这个函数会检查所有已定义的标志,并将它们与用户提供的值相匹配。

int main(int argc, char* argv[ ]) {gflags::ParseCommandLineFlags(&argc, &argv, true);// 程序逻辑...
}

5.3 访问标志值

一旦设置了标志并解析了命令行参数,就可以通过全局变量或特定的访问器函数来获取这些标志的当前值。
对于上面定义的标志,可以通过以下方式访问其值:

std::cout << "Hello, " << FLAGS_name << "!" << std::endl;

这里FLAGS_前缀加上标志的名字构成了全局变量名。

六、高级特性

gflags 是一个用于处理命令行参数的C++库,它提供了丰富的功能来简化命令行接口的设计。
下面我将通过示例代码展示 gflags 的三个高级特性:标志验证、文件加载和帮助信息显示。

6.1 标志验证

首先,我们需要定义一些标志,并为它们设置验证规则。这里我们使用 DEFINE_int32 来定义整数标志,并利用 SetValidator 函数来添加自定义验证逻辑。

#include <gflags/gflags.h>
#include <iostream>// 定义一个整型标志
DEFINE_int32(port, 8080, "The port to listen on");// 自定义验证函数
bool ValidatePort(const char* flagname, int32_t value) {if (value > 0 && value < 65536)  // 端口号应该在合法范围内return true;std::cerr << "Invalid value for --" << flagname << ": " << value << std::endl;return false;
}int main(int argc, char* argv[ ]) {// 初始化 gflagsgoogle::ParseCommandLineFlags(&argc, &argv, true);// 设置验证器google::FlagRegisterer::RegisterValidator(&FLAGS_port, &ValidatePort, "port must be between 1 and 65535");// 检查标志是否有效if (!ValidatePort("port", FLAGS_port)) {return 1;  // 如果端口无效,则退出程序}std::cout << "Listening on port: " << FLAGS_port << std::endl;return 0;
}

6.2 文件加载

gflags 支持从文件中读取配置。这可以通过指定特殊的命令行参数 --fromenv 或 --flagfile 实现。下面是一个简单的例子:

假设有一个名为 config.txt 的文件,内容如下:

--port=9090

然后你可以这样修改你的主函数以支持从文件加载配置:

int main(int argc, char* argv[ ]) {// 允许从环境变量或文件加载标志google::SetUsageMessage("Usage: example [options] --flagfile=config_file\n""Options:\n""  --help         : Show this help message.\n""  --flagfile     : Load flags from a file.\n");google::ParseCommandLineFlags(&argc, &argv, true);if (FLAGS_port == 9090) {  // 默认值std::cout << "Using default port." << std::endl;} else {std::cout << "Loaded port from config: " << FLAGS_port << std::endl;}return 0;
}

运行时可以这样调用:

./example --flagfile=config.txt

6.3 帮助信息

最后,打印所有可用标志及其描述可以帮助用户更好地理解如何使用应用程序。这通常通过 --help 参数实现。

int main(int argc, char* argv[ ]) {google::SetVersionString("1.0.0");  // 设置版本号google::SetUsageMessage("A simple server application.");google::ParseCommandLineFlags(&argc, &argv, true);if (google::IsHelpShortFlagPresent() || google::IsHelpLongFlagPresent()) {google::ShowUsageWithFlags();  // 显示帮助信息return 0;}// ... 其他代码
}

当用户运行程序并传递 --help 选项时,程序将显示所有的标志以及它们的默认值和描述。这有助于提高软件的可访问性和易用性。

原创 zgrxmm linux源码阅读

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

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

相关文章

【C++】Google benchmark理解与应用

一、介绍 Google Benchmark 是一个用于 C++ 的微基准测试库。它旨在帮助开发者编写出更高效、更具表现力的基准测试代码。通过使用 Google Benchmark,可以方便地测量函数或代码片段的性能,并且能够生成详细的报告。 二、安装与配置 2.1 安装 在Ubuntu环境中安装Google Benchm…

LRU浅析

LRU算法LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使…

20250205 省选模拟赛 T3

20250205 省选模拟赛 T3 Description 设计一个 \(n\times n\) 的 01 矩阵,使得从 \((1,1)\) 走到 \((n,n)\) 且只能向右或下走且只经过为 \(1\) 的格子的方案数为 \(X\)。 \(n \leq 24\) 时得满分。\(X \leq 10^9\)。 Solution 基于 \(2\) 进制的构造方法我们称从左上到右下的…

Automa:自动化浏览器工作流

🏷️仓库名称:AutomaApp/automa 🌟截止发稿星数: 14340 (今日新增:33) 🇨🇳仓库语言: Vue 🤝仓库开源协议:Other 🔗仓库地址:https://github.com/AutomaApp/automa引言 Automa是一个浏览器扩展,允许用户通过连接模块来自动化浏览器任务。它消除了重复性任务的需…

本地部署DeepSeek教程

本地部署DeepSeek教程 步骤 本地部署DeepSeek教程步骤 1 安装Ollama 2 下载DeepSeek模型 3 可视化图文交互界面Chatbox(可选)1 安装Ollama 访问Ollama官网下载Ollama,默认安装即可。安装完成后打开终端(我这里是windows系统),输入: ollama help即可查看ollama选项,且可…

OpenLDAP篇-安装OpenLDAP服务01

1、OpenLDAP统⼀⽤户认证系统 1.1 为什么需要OpenLDAP 在没有OpenLDAP统⼀⽤户认证系统的环境中,往往会⾯临如下问题:1、当⽤户需要访问多台服务器时,管理员需要在每台服务器上⼿动创建账户。如果员⼯离职,还需逐台删除账户,整体操作繁琐且容易出现遗漏的情况,因此存在较…

集训3 20240127

集训3 20240127 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ A: 题目大意:给定 \(n\) ,两个人轮流可以使 \(n\) 减去一个任意小于它且与它互质的数,求最后甲能否取胜 #include<bits/stdc++.h>using namespace std;int main() {long long n;cin&g…

RocketMQ实战—4.消息零丢失的方案

大纲 1.全链路分析为什么用户支付完成后却没有收到红包 2.RocketMQ的事务消息机制实现发送消息零丢失 3.RocketMQ事务消息机制的底层实现原理 4.是否可以通过同步重试方案来代替事务消息方案来实现发送消息零丢失 5.使用RocketMQ事务消息的代码案例细节 6.同步刷盘+Raft协议同步…

qoj7301 AGC036D 题解

qoj7301 orz yxx 有一个很牛的状态设计 \(f_{i,j,0/1}\),\(0\) 为 \(a_{i-1}>a_i\),\(j\) 记录 \(a_{i-1}\) 的值,\(a_i\) 的值未定;\(1\) 为 \(a_{i-1}<a_i\),\(j\) 记录 \(a_i\) 的值 这样可以完美解决 \(a_{i-1}>a_i<a_{i+1}\) 的问题 转移和优化都是简单的…

【PyTorch】对比Torch和Numpy

该部分主要通过对比Torch和Numpy基础知识,方便大家了解PyTorch。Numpy是处理数据的模块,处理各种矩阵的形式来多核加速运算。 Torch自称为神经网络界的Numpy,因为它能将torch产生的tensor(张量)放在 GPU 中加速运算(前提是你有合适的 GPU),就像Numpy会把array放在CPU中…

十. Redis 事务和 “锁机制”—— 并发秒杀处理的详细说明

十. Redis 事务和 “锁机制”——> 并发秒杀处理的详细说明 @目录十. Redis 事务和 “锁机制”——> 并发秒杀处理的详细说明1. Redis 的事务是什么?2. Redis 事务三特性3. Redis 关于事务相关指令 Multi、Exec、discard和 “watch & unwatch”3.1 快速入门(演示…

使用Tauri框架打造的FPS透视

使用Tauri框架打造的FPS透视,使用javascript读内存绘制透视框使用Vue前端和Rust后端打造FPS透视 前端使用P5js进行canvas绘制 后端封装内存读取工具,前端快速编写代码无需重启调试 Vue前端与后端通讯获取内存数据并在前端渲染 作者声明 [仅供学习 请勿非法用途 从事非法用途出…