吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1711|回复: 9
收起左侧

[C&C++ 原创] 一个C++开发的命令行参数解析的小工具

  [复制链接]
lmclmc 发表于 2023-9-15 17:32
本帖最后由 lmclmc 于 2023-9-15 17:43 编辑

先上链接
https://github.com/lmclmc/base-components-tool
该工具支持任意参数类型。支持参数依赖,参数范围,参数描述等设置

image.png

image.png

[C++] 纯文本查看 复制代码
#include "version.h"

#include "cmdline/cmdline.h"
#include "util/single.hpp"
#include "log/log.h"

#include <vector>
#include <list>
#include <set>
#include <queue>
#include <stack>
#include <deque>
#include <forward_list>
#include <unordered_set>

using namespace lmc;

int main(int argc, char *argv[])
{
    CmdLine *cmd = TypeSingle<CmdLine>::getInstance();
    cmd->add<std::vector<short>>("-s", "--short", "get short", {}, {33, 55});
    cmd->add<std::vector<unsigned short>>("-us", "--us", "get unsigned short");
    cmd->add<std::vector<int>>("-i", "--int", "get int");
    cmd->add<std::vector<unsigned int>>("-ui", "--ui", "get unsigned int",
                                        {"-s", "-us", "-i"});
    cmd->add<std::vector<float>>("-f", "--float", "get float", {}, {23, 100});
    cmd->add<std::vector<double>>("-d", "--double", "get double");
    cmd->add<std::vector<long>>("-l", "--long", "get long");
    cmd->add<std::vector<unsigned long>>("-ul", "--ul", "get unsigned long");
    cmd->add<std::vector<std::string>>("-string", "--string", "get string", 
                                       {}, {"aaa", "vvv", "bbb", "rrr", "ttt"});
    cmd->add<std::list<std::string>>("-ls", "--lstring", "get list string", 
                                     {}, {"aaa", "vvv", "bbb", "rrr", "ttt"});
    cmd->add<std::set<std::string>>("-ss", "--sstring", "get set string", 
                                    {}, {"aaa", "vvv", "bbb", "rrr", "ttt"});
    cmd->add<std::set<int>>("-si", "--sint", "get set int", 
                           {"-ss", "-us"}, {44, 99});
    cmd->add<std::deque<std::string>>("-ds", "--dstring", "get deque string", 
                                      {}, {"aaa", "vvv", "bbb", "rrr", "ttt"});
    cmd->add<std::deque<int>>("-di", "--dint", "get deque int", {}, {44, 99});
    cmd->add<std::queue<std::string>>("-dsss", "--queuestring", 
                                      "get queue string", 
                                      {}, std::queue<std::string>({"aaa", 
                                      "vvv", "bbb", "rrr", "ttt"}));
    cmd->add<std::queue<int>>("-diss", "--queueint", "get queue int", 
                              {}, std::queue<int>({44, 99}));
    cmd->add<std::stack<std::string>>("-dsa", "--stackstring", 
                                      "get stack string", 
                                      {}, std::stack<std::string>({"aaa", 
                                      "vvv", "bbb", "rrr", "ttt"}));
    cmd->add<std::stack<int>>("-dix", "--stackint", "get stack int", 
                              {}, std::stack<int>({44, 99}));
    cmd->add<std::forward_list<std::string>>("-flstring", 
                                             "--forwardliststring", 
                                             "get forward_list string", 
                                             {}, {"aaa", "vvv", "bbb", 
                                             "rrr", "ttt"});
    cmd->add<std::forward_list<int>>("-flint", "--forwardlistint", 
                                     "get forward_list int", {}, {44, 99});
    cmd->add<std::multiset<std::string>>("-mmstr", "--multisetstring", 
                                         "get multiset string", 
                                         {}, {"aaa", "vvv", "bbb", 
                                         "rrr", "ttt"});
    cmd->add<std::multiset<int>>("-mmint", "--multisetint", "get multiset int", 
                                 {}, {44, 99});
    cmd->add<std::unordered_set<std::string>>("-unstr", "--unorderedsetstring", 
                                              "get unordered_set string", 
                                              {}, {"aaa", "vvv", "bbb", 
                                              "rrr", "ttt"});
    cmd->add<std::unordered_set<int>>("-unint", "--unorderdsetint", 
                                      "get unordered_set int", {}, {44, 99});
    cmd->add<std::unordered_multiset<std::string>>("-unmstr", 
                                                   "--unorderedmsetstring", 
                                                   "get unordered_multiset string", 
                                                   {}, 
                                                   {"aaa", "vvv", "bbb", "rrr"});
    // add specified type of variable.
    // 1st argument is short name
    // 2nd argument is long name
    // 3rd argument is description
    // 4th argument is depends option
    // 5th argument is paramter ranage
    cmd->add<std::unordered_multiset<int>>("-unmint", "--unorderdmsetint", 
                                           "get unordered_multiset int", 
                                           {"-dix"}, {44, 99});
    // add specified type of variable.
    // 1st argument is long name
    // 2nd argument is short name (no short name if '\0' specified)
    // 3rd argument is description
    // 4th argument is depends option
    cmd->add("-n", "--none", "get none", {"-s", "-us", "-i"});
    // add specified type of variable.
    // 1st argument is long name
    // 2nd argument is short name (no short name if '\0' specified)
    // 3rd argument is description
    // 4th argument is depends option
    // 5th argument is paramter ranage
    cmd->add<std::string>("-sns", "--singlestring", "get single string", 
                         {"-s", "-us", "-i"}, 
                         {"aaa", "vvv", "bbb", "rrr", "ttt"});
    cmd->add<int>("-sni1", "--singleint1", "get single int1", 
                 {"-s", "-us", "-i"}, {12, 33});
    cmd->add<int>("-sni2", "--singleint2", "get single int2", 
                 {"-s", "-us", "-i"}, {12, 33});
    cmd->add("-v", "--version", "get version");
 
    cmd->parse(false, argc, argv);

    Logger::setLevel(LogLevel::all);

    bool ret = cmd->get("--none");
    if (ret)
    {
        LOGGER << "--none enable";
    }

    ret = cmd->get("--version");
    if (ret)
    {
        LOGGER << "version: " << PROJECT_VERSION;
    }

    std::string singleStr;
    ret = cmd->get("--singlestring", singleStr);
    if (ret)
    {
        LOGGER << singleStr;
    }

    int singleInt1;
    ret = cmd->get("--singleint1", singleInt1);
    if (ret)
    {
        LOGGER << singleInt1;
    }

    int singleInt2;
    ret = cmd->get("--singleint2", singleInt2);
    if (ret)
    {
        LOGGER << singleInt2;
    }

    std::vector<short> sVector;
    ret = cmd->get("--short", sVector);
    if (ret)
    {
        for (auto &v : sVector)
        {
            LOGGER << v;
        }
    }

    std::vector<unsigned short> usVector;
    ret = cmd->get("--us", usVector);
    if (ret)
    {
        for (auto &v : usVector)
        {
            LOGGER << v;
        }
    }

    std::vector<unsigned int> uiVector;
    ret = cmd->get("--ui", uiVector);
    if (ret)
    {
        for (auto &v : uiVector)
        {
            LOGGER << v;
        }
    }

    std::vector<int> iVector;
    ret = cmd->get("--int", iVector);
    if (ret)
    {
        for (auto &v : iVector)
        {
            LOGGER << v;
        }
    }

    std::vector<float> fVector;
    ret = cmd->get("--float", fVector);
    if (ret)
    {
        for (auto &v : fVector)
        {
            LOGGER << v;
        }
    }

    std::vector<double> dVector;
    ret = cmd->get("--double", dVector);
    if (ret)
    {
        for (auto &v : dVector)
        {
            LOGGER << v;
        }
    }

    std::vector<long> lVector;
    ret = cmd->get("--long", lVector);
    if (ret)
    {
        for (auto &v : lVector)
        {
            LOGGER << v;
        }
    }

    std::vector<unsigned long> ulVector;
    ret = cmd->get("--ul", ulVector);
    if (ret)
    {
        for (auto &v : ulVector)
        {
            LOGGER << v;
        }
    }
 
    std::vector<std::string> strVector;
    ret = cmd->get("--string", strVector);
    if (ret)
    {
        for (auto &v : strVector)
        {
            LOGGER << v;
        }
    }

    std::list<std::string> strList;
    ret = cmd->get("--lstring", strList);
    if (ret)
    {
        for (auto &v : strList)
        {
            LOGGER << v;
        }
    }

    std::set<std::string> strSet;
    ret = cmd->get("--sstring", strSet);
    if (ret)
    {
        for (auto &v : strSet)
        {
            LOGGER << v;
        }
    }

    std::set<int> intSet;
    ret = cmd->get("--sint", intSet);
    if (ret)
    {
        for (auto &v : intSet)
        {
            LOGGER << v;
        }
    }

    std::deque<std::string> strDeque;
    ret = cmd->get("--dstring", strDeque);
    if (ret)
    {
        for (auto &v : strDeque)
        {
            LOGGER << v;
        }
    }

    std::deque<int> intDeque;
    ret = cmd->get("--dint", intDeque);
    if (ret)
    {
        for (auto &v : intDeque)
        {
            LOGGER << v;
        }
    }

    std::queue<std::string> strQueue;
    ret = cmd->get("--queuestring", strQueue);
    if (ret)
    {
        int size = strQueue.size();
        for (int i = 0; i < size; i++)
        {
            auto s = strQueue.front();
            LOGGER << s;
            strQueue.pop();
        }
    }

    std::queue<int> intQueue;
    ret = cmd->get("--queueint", intQueue);
    if (ret)
    {
        int size = intQueue.size();
        for (int i = 0; i < size; i++)
        {
            auto s = intQueue.front();
            LOGGER << s;
            intQueue.pop();
        }
    }

    std::stack<std::string> strStack;
    ret = cmd->get("--stackstring", strStack);
    if (ret)
    {
        int size = strStack.size();
        for (int i = 0; i < size; i++)
        {
            auto s = strStack.top();
            LOGGER << s;
            strStack.pop();
        }
    }

    std::stack<int> intStack;
    ret = cmd->get("--stackint", intStack);
    if (ret)
    {
        int size = intStack.size();
        for (int i = 0; i < size; i++)
        {
            auto s = intStack.top();
            LOGGER << s;
            intStack.pop();
        }
    }

    std::forward_list<std::string> strForwardList;
    ret = cmd->get("--forwardliststring", strForwardList);
    if (ret)
    {
        for (auto &v : strForwardList)
        {
            LOGGER << v;
        }
    }

    std::forward_list<int> intForwardList;
    ret = cmd->get("--forwardlistint", intForwardList);
    if (ret)
    {
        for (auto &v : intForwardList)
        {
            LOGGER << v;
        }
    }

    std::multiset<std::string> strMultiset;
    ret = cmd->get("--multisetstring", strMultiset);
    if (ret)
    {
        for (auto &v : strMultiset)
        {
            LOGGER << v;
        }
    }

    std::multiset<int> intMultiset;
    ret = cmd->get("--multisetint", intMultiset);
    if (ret)
    {
        for (auto &v : intMultiset)
        {
            LOGGER << v;
        }
    }

    std::unordered_set<std::string> strUnorderedset;
    ret = cmd->get("--unorderedsetstring", strUnorderedset);
    if (ret)
    {
        for (auto &v : strUnorderedset)
        {
            LOGGER << v;
        }
    }

    std::unordered_set<int> intUnorderedset;
    ret = cmd->get("--unorderdsetint", intUnorderedset);
    if (ret)
    {
        for (auto &v : intUnorderedset)
        {
            LOGGER << v;
        }
    }

    std::unordered_multiset<std::string> strUnorderedmultiset;
    ret = cmd->get("--unorderedmsetstring", strUnorderedmultiset);
    if (ret)
    {
        for (auto &v : strUnorderedmultiset)
        {
            LOGGER << v;
        }
    }

    std::unordered_multiset<int> intUnorderedmultiset;
    ret = cmd->get("--unorderdmsetint", intUnorderedmultiset);
    if (ret)
    {
        for (auto &v : intUnorderedmultiset)
        {
            LOGGER << LogFormat::addr << v;
        }
    }
}

接口展示
[C++] 纯文本查看 复制代码
class CmdLine
{
public:
    CmdLine() = default;
    ~CmdLine() = default;
    
    /**
     * @brief add 设置命令行选项以及附带参数
     * @Param shortName 选项短名称
     * @param name 选项长名称
     * @param describtion 选项描述
     * @param dep 可选参数,选项依赖
     * @param range 可选参数,参数范围
     * @Return 返回无
     */
    template<//STL_T是用户定义的数据类型,有可能是容器,但也有可能不是
             typename STL_T = None<int>,
             //STL_STR是选项依赖的数据类型。它是个容器,内部类型使用std::string
             //具体使用哪个容器与STL_T容器保持一致,如果STL_T不是容器则默认使用list
             typename STL_STR = STL_NEW_T<STL_T, std::string>,
             //STL_R是参数范围的数据类型。它是个容器,内部类型与用户容器内部类型保持一致
             //具体使用哪个容器与STL_T容器保持一致,如果STL_T不是容器则默认使用list
             typename STL_R = STL_NEW_T<STL_T, typename IsStl<STL_T>::FinalT>>
    void add(const std::string &shortName, const std::string &name,
             const std::string &describtion, STL_STR dep = STL_STR(), 
             STL_R range = STL_R())
    {
        paramTable.emplace_back(std::make_shared<ParamWithValue<STL_T>>(name, 
                                                 shortName, describtion, dep, 
                                                 range));
    }

    /**
     * @brief get 获取选项信息,或者获取参数信息,注意参数只能获取一次
     * @param name 选项名称
     * @param t  获取参数信息
     * @return 返回 选项使能 true 否则 false
     */
    template<typename STL_T = None<int>>
    bool get(const std::string &name, STL_T &&t = STL_T())
    {
        for (auto &l : paramTable)
        {
            if ((l->getName() == name || l->getShortName() == name) &&
                 l->getEnable())
            {
                //移除STL_T多余的类型修饰信息,const volatile等等。
                using STL_T_ = RemoveCVREF<STL_T>;
                auto p = std::dynamic_pointer_cast<ParamWithValue<STL_T_>>(l);
                t = std::move(p->get());
                return true;
            }
        }
        return false;
    }

    /**
     * @brief parse 解析命令行参数
     * @param noParam 没有命令行参数,是否继续运行,true :是 false: 否
     * @param argc 命令行参数数量
     * @param argv 命令行参数列表
     * @return 返回 选项使能 true 否则 false
     */
    void parse(bool noParam, int argc, char *argv[]);

private:
    void showHelp();
    void paramCheck();

private:
    std::list<std::shared_ptr<ParamBase>> paramTable;
    std::string cmd;
};

免费评分

参与人数 4吾爱币 +9 热心值 +3 收起 理由
lzyjue0417 + 1 热心回复!
wushaominkk + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
zhczf + 1 我很赞同!
supercilious + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

xixicoco 发表于 2023-9-16 01:41
不是看的太懂,好像是不错的通用工具
Galaxy2010 发表于 2023-9-16 12:12
 楼主| lmclmc 发表于 2023-9-16 12:35
Triple.J 发表于 2023-9-17 21:21
有大佬能再简化一下吗?还是搞不太来
 楼主| lmclmc 发表于 2023-9-18 14:44
Triple.J 发表于 2023-9-17 21:21
有大佬能再简化一下吗?还是搞不太来

哪里有问题,你截图出来
coolbye 发表于 2023-9-19 09:28
这个看上去好复杂的样子,没有popt简洁
 楼主| lmclmc 发表于 2023-9-19 10:52
coolbye 发表于 2023-9-19 09:28
这个看上去好复杂的样子,没有popt简洁

关键是我行数少啊,头文件,源文件加起来1000行左右
greatzdl 发表于 2023-9-19 13:22
很不错 下次直接用你的这个
aft705 发表于 2023-12-2 10:25
好长好长。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 17:47

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表