一个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;
        }
    }
}

 接口演示:www.soo6.net

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;
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值