【问题标题】:Selecting option group according the first option根据第一个选项选择选项组
【发布时间】:2014-08-27 20:57:49
【问题描述】:

我已经实现了一个应用程序(我们称之为“应用程序”),它执行两种类型的任务,TATB。每种类型的任务的命令行选项都不同。这就是为什么我决定用户将使用“命令”指定任务类型:

app command_a --opt_1  --opt_2     # For TA
app command_b --opt_3  --opt_4     # For TB

当然command_acommand_b 是互斥的。 (你可以看到如何做到这一点here

问题 1:选择我们将使用哪个options_description 对象解析命令行的最佳方法是什么?

问题 2: 实现命令帮助系统的最佳方式是什么?示例:

app help command_a              # Display help for TA

【问题讨论】:

    标签: c++ boost boost-program-options


    【解决方案1】:

    这是我研究图书馆 2 小时后可以实现的最佳答案。我将此作为答案发布,因为在某种程度上给出了问题的解决方案,但我知道很可能有人会提供更好的解决方案。

    选择我们将使用哪个 options_description 对象解析命令行的最佳方法是什么?

    到目前为止,我设法根据第一个选项在两个 options_description 对象之间进行选择(更多详细信息请参见代码)。我所做的如下:

    1. 创建两个 options_descrition 对象OptDescA 用于 TAOptDescB 用于 TB
    2. 检查第一个参数是command_a 还是command_b
    3. 根据第一个参数,我使用OptDescAOptDescB 解析命令行

    对于第 3 点,我必须将 argc 减一并将 argv 指针 1 向前移动。

    po::store(po::parse_command_line(argc - 1, argv + 1, OptDescA), vm);
    

    这样我就不必在OptDescAOptDescB 中处理command_acommand_b

    实现“命令”帮助系统的最佳方式是什么。

    嗯,这是(实际上是)对我来说最困难的。实现细节参见下面的代码。

    我的帮助系统的问题是我必须输入:

    app help command_a
    

    而不是最常见的:

    app command_a help
    

    除了你输入 app help 后,输出是:

    Available commands:
    
     --help arg            Display this message
     --command_a           Do command_a stuff
     --command_b           Do command_b stuff
    

    注意丑陋的--help arg

    代码

    #include <iostream>
    #include <string>
    #include <boost/program_options.hpp>
    
    using namespace std;
    
    
    void help_system(string target);
    
    
    int main(int argc, char *argv[]) 
    {
        namespace po = boost::program_options;
    
        po::options_description command_a("Command_a options");
        command_a.add_options()
            ("option_1", po::value<int>()->required(), "option_1 desc")
            ("option_2", po::value<int>()->required(), "option_2 desc")
            ;
    
        po::options_description command_b("Command_b options");
        command_b.add_options()
            ("option_3", po::value<int>()->required(), "option_3 desc")
            ("option_4", po::value<int>()->required(), "option_4 desc")
            ;
    
        po::options_description commands("Available commands");
        commands.add_options()
            ("help", po::value<string>()->default_value(""), "Display this message")
            ("command_a", "Do command_a stuff")
            ("command_b", "Do command_b stuff")
            ;
    
        po::variables_map vm;
    
        if (string("command_a") == string(*(argv + 1))) {
    
            try{ po::store(po::parse_command_line(argc - 1, argv + 1, command_a), vm); }
            catch (exception &e){ cout << "Error: " << e.what() << endl; }
        }
        else if (string("command_b") == string(*(argv + 1))) {
    
            try{ po::store(po::parse_command_line(argc - 1, argv + 1, command_b), vm); }
            catch (exception &e){ cout << "Error: " << e.what() << endl; }
        }
        else if (string("help") == string(*(argv + 1)))
        {
            cout << commands << endl;
        }
    
        try { po::notify(vm); }
        catch (exception &e) { cout << "Error: " << e.what() << endl; }
    
        return 0;
    }
    
    
    void help_system(string target)
    {
        if (target.c_str() == "command_a") {}  // The ideal is to do "cout << command_a" here
                                               // but right now command_a is out of the scope.
        if (target.c_str() == "command_b") {}
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-11-07
      • 2018-08-25
      • 2013-01-13
      • 1970-01-01
      • 2020-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多