【C++】开源:命令行解析库CLI11配置与使用

😏★,°:.☆( ̄▽ ̄)/$:.°★ 😏
这篇文章主要介绍命令行解析库CLI11配置与使用。
无专精则不能成,无涉猎则不能通。——梁启超
欢迎来到我的博客,一起学习,共同进步。
喜欢的朋友可以关注一下,下次更新不迷路🥞

文章目录

    • :smirk:1. 项目介绍
    • :blush:2. 环境配置
    • :satisfied:3. 使用说明

😏1. 项目介绍

项目Github地址:https://github.com/CLIUtils/CLI11

看到一位朋友的评论,说平时命令行解析库用CLI11的多,这里来学习一下。

CLI11 是一个用于处理命令行参数和选项的 C++ 库,旨在简化 C++ 应用程序的命令行界面开发。

主要特点:

1.简单易用:CLI11 的设计目标之一是提供一个简单且直观的 API,使开发者能够轻松地定义和解析命令行选项。

2.现代 C++ 支持:CLI11 充分利用了现代 C++ 的特性,包括类型推导、lambda 表达式等,使其在语法上更为优雅和灵活。

3.丰富的选项支持:支持多种命令行选项,包括标志选项(flags)、位置参数、可选参数、必选参数等,可以方便地定义各种复杂的命令行接口。

4.类型安全:CLI11 在解析和处理命令行参数时,提供了类型安全的机制,避免了常见的类型转换错误。

5.灵活的错误处理:提供了多种错误处理方式,包括参数验证失败时的错误提示、帮助信息的自动生成等。

6.跨平台支持:CLI11 可以在主流的操作系统上运行,包括 Windows、macOS 和各种 Linux 发行版,确保了跨平台的兼容性。

😊2. 环境配置

ubuntu源码安装CLI11库:

git clone https://github.com/CLIUtils/CLI11.git
mkdir build & cd build
cmake ..
make
sudo make install

程序g++编译(不用加-lCLI11):g++ -o main main.cpp

😆3. 使用说明

下面是一个解析命令行的示例:

#include <CLI/CLI.hpp>
#include <iostream>

int main(int argc, char **argv) {
    CLI::App app{"CLI11 example"};

    std::string name;
    app.add_option("-n,--name", name, "Your name")->required();

    CLI11_PARSE(app, argc, argv);

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

    return 0;
}

官方还给出了一些示例,如通过命令行检查(如文件、数字范围):

// Copyright (c) 2017-2024, University of Cincinnati, developed by Henry Schreiner
// under NSF AWARD 1414736 and by the respective contributors.
// All rights reserved.
//
// SPDX-License-Identifier: BSD-3-Clause

#include <CLI/CLI.hpp>
#include <iostream>
#include <string>

int main(int argc, char **argv) {

    CLI::App app("Validator checker");

    std::string file;
    app.add_option("-f,--file,file", file, "File name")->check(CLI::ExistingFile);

    int count{0};
    app.add_option("-v,--value", count, "Value in range")->check(CLI::Range(3, 6));
    CLI11_PARSE(app, argc, argv);

    return 0;
}

此外还可以和json库一起使用:

// Copyright (c) 2017-2021, University of Cincinnati, developed by Henry Schreiner
// under NSF AWARD 1414736 and by the respective contributors.
// All rights reserved.
//
// SPDX-License-Identifier: BSD-3-Clause

#include <CLI/CLI.hpp>
#include <iostream>
#include <memory>
#include <nlohmann/json.hpp>
#include <string>
#include <vector>

// This example is only built on GCC 7 on Travis due to mismatch in stdlib
// for clang (CLI11 is forgiving about mismatches, json.hpp is not)

using nlohmann::json;

class ConfigJSON : public CLI::Config {
  public:
    std::string to_config(const CLI::App *app, bool default_also, bool, std::string) const override {

        json j;

        for(const CLI::Option *opt : app->get_options({})) {

            // Only process option with a long-name and configurable
            if(!opt->get_lnames().empty() && opt->get_configurable()) {
                std::string name = opt->get_lnames()[0];

                // Non-flags
                if(opt->get_type_size() != 0) {

                    // If the option was found on command line
                    if(opt->count() == 1)
                        j[name] = opt->results().at(0);
                    else if(opt->count() > 1)
                        j[name] = opt->results();

                    // If the option has a default and is requested by optional argument
                    else if(default_also && !opt->get_default_str().empty())
                        j[name] = opt->get_default_str();

                    // Flag, one passed
                } else if(opt->count() == 1) {
                    j[name] = true;

                    // Flag, multiple passed
                } else if(opt->count() > 1) {
                    j[name] = opt->count();

                    // Flag, not present
                } else if(opt->count() == 0 && default_also) {
                    j[name] = false;
                }
            }
        }

        for(const CLI::App *subcom : app->get_subcommands({}))
            j[subcom->get_name()] = json(to_config(subcom, default_also, false, ""));

        return j.dump(4);
    }

    std::vector<CLI::ConfigItem> from_config(std::istream &input) const override {
        json j;
        input >> j;
        return _from_config(j);
    }

    std::vector<CLI::ConfigItem>
    _from_config(json j, std::string name = "", std::vector<std::string> prefix = {}) const {
        std::vector<CLI::ConfigItem> results;

        if(j.is_object()) {
            for(json::iterator item = j.begin(); item != j.end(); ++item) {
                auto copy_prefix = prefix;
                if(!name.empty())
                    copy_prefix.push_back(name);
                auto sub_results = _from_config(*item, item.key(), copy_prefix);
                results.insert(results.end(), sub_results.begin(), sub_results.end());
            }
        } else if(!name.empty()) {
            results.emplace_back();
            CLI::ConfigItem &res = results.back();
            res.name = name;
            res.parents = prefix;
            if(j.is_boolean()) {
                res.inputs = {j.get<bool>() ? "true" : "false"};
            } else if(j.is_number()) {
                std::stringstream ss;
                ss << j.get<double>();
                res.inputs = {ss.str()};
            } else if(j.is_string()) {
                res.inputs = {j.get<std::string>()};
            } else if(j.is_array()) {
                for(std::string ival : j)
                    res.inputs.push_back(ival);
            } else {
                throw CLI::ConversionError("Failed to convert " + name);
            }
        } else {
            throw CLI::ConversionError("You must make all top level values objects in json!");
        }

        return results;
    }
};

int main(int argc, char **argv) {
    CLI::App app;
    app.config_formatter(std::make_shared<ConfigJSON>());

    int item;

    app.add_flag("--simple");
    app.add_option("--item", item);
    app.set_config("--config");

    CLI11_PARSE(app, argc, argv);

    std::cout << app.config_to_str(true, true) << std::endl;
}

在这里插入图片描述

以上。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

苹果清理软件:让你的设备焕然一新

随着时间的推移&#xff0c;无论是Mac电脑还是iOS设备&#xff0c;都可能会因为积累的垃圾文件、缓存、未使用的应用和其他冗余数据而开始表现出性能下降。这不仅会占用宝贵的存储空间&#xff0c;还可能影响设备的响应速度和电池寿命。幸运的是&#xff0c;有多种苹果清理软件…

Zabbix监控软件

目录 一、什么是Zabbix 二、zabbix监控原理 三、zabbix 安装步骤 一、什么是Zabbix ●zabbix 是一个基于 Web 界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。 ●zabbix 能监视各种网络参数&#xff0c;保证服务器系统的安全运营&#xff1b;并提供灵活的…

使用labelme中的AI多边形(AI-polygon)标注 win版exe Create AI-Polygon闪退

这里写目录标题 虚拟环境创建labelme虚拟环境下载AI标注模型win Labelme.exe Create AI-Polygon闪退问题也用如下方法解决 win Labelme.exe Create AI-Polygon闪退问题也用如下方法解决愉快地使用labelme的AI标注工具 虚拟环境 创建labelme虚拟环境 创建基础环境并激活 cond…

2007-2022年 国内各上市公司绿色化转型数据.(Excel文件、dta文件、参考文献、计算方法与说明)

上市公司绿色化转型数据为研究者提供了评估企业在生态文明建设、循环经济和绿色管理方面表现的重要视角。以下是对中国各上市公司绿色化转型数据的介绍&#xff1a; 数据简介 定义&#xff1a;上市公司绿色化转型是指企业在发展模式上向可持续发展转变&#xff0c;实现资源节…

摸鱼大数据——Spark SQL——基本介绍和入门案例

Spark SQL 基本介绍 1、什么是Spark SQL Spark SQL是Spark多种组件中其中一个&#xff0c;主要是用于处理大规模的【结构化数据】 什么是结构化数据: 一份数据, 每一行都有固定的列, 每一列的类型都是一致的 我们将这样的数据称为结构化的数据例如: mysql的表数据1 张三 202 …

hid-ft260驱动学习笔记 1 - 驱动模块注册与注销

目录 1. ft260_driver_init初始化 1.1 tty设备 1.1.1 申请tty驱动设备 1.1.2 初始化tty驱动程序 1.1.3 注册tty设备 1.2 hid设备 2. ft260_driver_exit注销模块 3. 调试 hid-ft260.c的最底部可以看到该驱动的注册与注销接口的申明。 module_init(ft260_driver_init); …

【基于R语言群体遗传学】-8-代际及时间推移对于变异的影响

上一篇博客&#xff0c;我们学习了在非选择下&#xff0c;以二项分布模拟遗传漂变的过程&#xff1a;【基于R语言群体遗传学】-7-遗传变异&#xff08;genetic variation&#xff09;-CSDN博客 那么我们之前有在代际之间去模拟&#xff0c;那么我们就想知道&#xff0c;遗传变…

LabVIEW透视变换

透视变换概述源程序在www.bjcyck.com下载 透视变换是一种几何变换&#xff0c;用于对图像进行扭曲&#xff0c;使其看起来从不同角度拍摄。这在计算机视觉和图像处理领域非常重要&#xff0c;例如在投影校正和图像配准中。LabVIEW提供了强大的图像处理工具&#xff0c;利用其V…

java生成json格式文件(包含缩进等格式)

生成json文件的同时保留原json格式&#xff0c;拥有良好的格式&#xff08;如缩进等&#xff09;&#xff0c;提供友善阅读支持。 pom.xml依赖增加&#xff1a; <dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactI…

LabVIEW在图像处理中的应用

abVIEW作为一种图形化编程环境&#xff0c;不仅在数据采集和仪器控制领域表现出色&#xff0c;还在图像处理方面具有强大的功能。借助其Vision Development Module&#xff0c;LabVIEW提供了丰富的图像处理工具&#xff0c;广泛应用于工业检测、医学影像、自动化控制等多个领域…

Linux防火墙使用(firewalld与iptables)

防火墙概述 防火墙是一种由硬件和软件组合而成&#xff0c;在内部网和外部网之间、专有网和公共网之间构造的保护屏障&#xff0c;用以保护用户资料和信息安全的一种技术 防火墙作用在于及时发现并处理计算机网络运行时可能存在的安全风险、数据传输等问题&#xff0c;从而实现…

Java | Leetcode Java题解之第212题单词搜索II

题目&#xff1a; 题解&#xff1a; class Solution {int[][] dirs {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};public List<String> findWords(char[][] board, String[] words) {Trie trie new Trie();for (String word : words) {trie.insert(word);}Set<String> a…

Apache Seata Mac下的Seata Demo环境搭建

本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 本文来自 Apache Seata官方文档&#xff0c;欢迎访问官网&#xff0c;查看更多深度文章。 Mac下的Seata Demo环境搭建&#xff08;AT模式&#xff09; 前言 最近因为工作需要&#xf…

探讨3D沉浸式在线会议系统的研发 - Meta演示的元宇宙虚拟化身多人对话场景,Web端现在也可以实现了 !

要实现一个元宇宙多人会议系统&#xff0c;关键技术有&#xff1a; 1. 3D虚拟空间的构建&#xff08;含光影特效、虚拟现实和增强现实&#xff09; 2. 3D虚拟化身的构建&#xff08;含动画、表情、语音&#xff09; 3. 多人角色管理 4. 会话控制和信息同步 5. 语音合成 6…

免费的鼠标连点器电脑版教程!官方正版!专业鼠标连点器用户分享教程!2024最新

电脑技术的不断发展&#xff0c;许多用户在日常工作和娱乐中&#xff0c;需要用到各种辅助工具来提升效率或简化操作&#xff0c;而电脑办公中&#xff0c;鼠标连点器作为一种能够模拟鼠标点击的软件&#xff0c;受到了广大用户的青睐。本文将为大家介绍一款官方正版的免费鼠标…

对接海康sdk-linux下复制jar包中resource目录的文件夹

背景 在集成海康sdk时,需要将一些组件放到项目中作为静态资源,并且海康的sdk初始化也需要加载这些静态资源,在windows下,使用一些File路径的方式是可以正确加载的,但是在linux上就会加载失败。 首先我是将海康的sdk组件放到resource下的,并且按照windows和linux设置了两…

考虑数据库粒度的设计-提升效率

目录 概要 场景 设计思路 小结 概要 公开的资料显示&#xff0c;数据库粒度是&#xff1a;“在数据库领域&#xff0c;特别是数据仓库的设计中&#xff0c;粒度是一个核心概念&#xff0c;它直接影响到数据分析的准确性和存储效率。粒度的设定涉及到数据的详细程度和精度&…

CH11_JS的多重循环

第11章&#xff1a;Javascript的多重循环 本章目标 掌握二重循环的使用 掌握二重循环的控制语句的使用 课程回顾 循环控制有那几种方式 讲解内容 1. 回顾练习 需求说明 某次程序大赛&#xff0c;AI2101班有4名学员参加&#xff0c;学员的成绩由用户输入&#xff0c;计算…

文件系统技术架构分析

一文读懂&#xff1a;什么是文件系统 &#xff0c;有哪几类&#xff1f; ▉ 什么是文件系统&#xff1f; 技术大拿眉头皱了皱&#xff0c;忍住快要爆发的情绪。解释到&#xff1a; 数据以二进制形式存储于介质&#xff0c;但高低电平含义难解。文件系统揭秘这些二进制背后的意…

【踩坑】修复pyinstaller报错 No module named pkg_resources.extern

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 报错如下&#xff1a; 修复方法&#xff1a; pip install --upgrade setuptools pippyinstaller -F -w main.py --hidden-importpkg_resources.py2_wa…