【问题标题】:How do you handle command line options and config files?你如何处理命令行选项和配置文件?
【发布时间】:2010-11-02 15:55:06
【问题描述】:

您使用哪些软件包来处理命令行选项、设置和配置文件?

我正在寻找从命令行和/或配置文件读取用户定义选项的东西。

选项(设置)应该可以分成不同的组,这样我就可以在我的代码中将不同的(子集)选项传递给不同的对象。

我知道boost::program_options,但我不太习惯API。有轻量级的替代品吗?

(顺便说一句,您是否曾经在代码中使用可以从任何地方读取的全局选项对象?或者您会认为这是邪恶的吗?)

【问题讨论】:

    标签: c++ command-line configuration-files options configuration-management


    【解决方案1】:

    在 Google,我们使用 gflags。它不做配置文件,但对于标志,它比使用 getopt 痛苦得多。

    #include <gflags/gflags.h>
    DEFINE_string(server, "foo", "What server to connect to");
    int main(int argc, char* argv[]) {
        google::ParseCommandLineFlags(&argc, &argv, true);
        if (!server.empty()) {
            Connect(server);
        }
    }
    

    您将DEFINE_foo 放在需要知道标志值的文件的顶部。如果其他文件也需要知道该值,则在其中使用DECLARE_foo。对测试也有很好的支持,所以单元测试可以独立设置不同的标志。

    【讨论】:

    • 我喜欢!看起来很容易使用。
    【解决方案2】:

    对于命令行和 C++,我一直是 TCLAP 的粉丝:模板化命令行参数解析器。

    http://sourceforge.net/projects/tclap/

    【讨论】:

      【解决方案3】:

      好吧,你不会喜欢我的回答。我使用boost::program_options。该界面需要一些时间来适应,但是一旦您将其关闭,那就太棒了。只需确保进行大量单元测试,因为如果语法错误,您将得到运行时错误。

      而且,是的,我将它们存储在一个单例对象中(只读)。在那种情况下,我不认为这是邪恶的。这是我能想到的少数几个可以接受单例的情况之一。

      【讨论】:

      • +1 表示 boost::program_options,但仅此而已!我会小心使用程序选项作为单例。我们一直被这样做所困扰,因为我们现在需要为不同的文件添加不同的选项集。我们首先需要返回并删除单例,以便我们可以为每个单独的文件存储不同的选项集。
      • 好点,理查德。我在游戏中使用 boost::program_options,显然每个进程一组选项就足够了,但对于不同的目的,这将是一个坏主意。
      • 你还支持 boost::program_options 吗?它似乎不再开发(文档网站最后一次修改是 2004 年)。它是否使用/与 c++11 兼容?在阅读文章的字里行间时,这实际上根本不是一个好的建议:只要确保进行大量的单元测试,因为如果语法错误,就会出现运行时错误红旗!
      【解决方案4】:

      如果 Boost 对你来说太过分了,GNU Gengetopt 也可能是,但恕我直言,这是一个有趣的工具。

      而且,我尽量远离全局选项对象,我更喜欢让每个类都读取自己的配置。除了整个“全局变量是邪恶的”哲学之外,将所有配置集中在一个地方往往会变得越来越混乱,而且很难判断在哪里使用了哪些配置变量。如果您将配置保持在更接近使用位置的位置,则每个配置的用途会更加明显,并且更易于保持清洁。

      (就我个人而言,我最近使用的所有东西都是我公司的其他人编写的专有命令行解析库,但不幸的是,这对你没有多大帮助)

      【讨论】:

        【解决方案5】:

        我已经使用 TCLAP 一两年了,但我偶然发现了ezOptionParser。 ezOptionParser 不会像其他选项解析器那样遭受“它不应该如此复杂”的综合症。

        到目前为止,我印象非常深刻,我很可能会继续使用它,特别是因为它支持配置文件。 TCLAP 是一个更复杂的库,但 ezOptionParser 的简单性和额外功能非常引人注目。

        其网站的其他好处包括(截至 0.2.0):

        • 漂亮打印已解析的输入以进行调试。
        • 在三种布局(对齐、交错或交错)中自动创建使用消息。
        • 单个头文件实现。
        • 仅依赖于 STL。
        • 任意短选项名称和长选项名称(不需要短划线“-”或加“+”前缀)。
        • 任意参数列表分隔符。
        • 允许多个标志实例。
        • 验证所需选项、每个标志的预期参数数量、数据类型范围、用户定义范围、列表中的成员资格和字符串列表的大小写。
        • 可由字符串或常量定义的验证标准。
        • 使用 cmets 导入多个文件。
        • 导出到文件,设置选项或所有选项,包括可用的默认值。
        • 订单相关上下文的选项解析索引。

        【讨论】:

        • 我知道这是一个非常古老的线程,但只是为了避免其他人在阅读此线程后陷入与我一样的陷阱。 ezOptionParser 可以很好地实际解析选项,但是如果您使用 getUsage() 函数来报告命令行选项,它有一个致命的错误会导致您的应用程序崩溃。作者现在不支持这个库,所以这个bug永远不会修复。谨慎使用;或者更好,使用别的东西。
        【解决方案6】:

        GNU getopt 非常好。如果您想要 C++ 的感觉,请考虑 getoptpp,它是原生 getopt 的包装器。 就配置文件而言,你应该尽量让它变得愚蠢,以便于解析。如果你有点体贴,你可能会想使用 yaac&lex,但这对于小型应用程序来说确实是一大笔钱。

        我还想建议您在应用程序中同时支持配置文件和命令行选项。配置文件更适合那些更改频率较低的选项。当您想要传递即时变化的参数时(通常是在您创建一个应用程序时,它会被其他程序调用)时,命令行选项非常有用。

        【讨论】:

          【解决方案7】:

          如果您在 x86 和 x64 Windows 上使用 Visual Studio 2005,SimpleLibPlus library 中有一些很好的命令行解析实用程序。我用过它,发现它非常有用。

          【讨论】:

            【解决方案8】:

            不确定命令行参数解析。我在该领域不需要非常丰富的功能,并且通常会推出自己的功能以节省向我的软件添加更多依赖项。根据您的需求,您可能想也可能不想尝试这条路线。我写的C++程序一般不会从命令行调用。

            另一方面,对于配置文件,您确实无法击败基于 XML 的格式。它是可读的、可扩展的、结构化的等等...... :) 另外还有很多 XML 解析器。尽管它是一个 C 库,但我倾向于使用来自 xmlsoft.org 的 libxml2。

            【讨论】:

            • 查看pugixml.org 了解用 C++ 编写的快速 XML 解析器。作为奖励,它支持XPath,并且也只是标题!
            【解决方案9】:

            试试Apache Ant。它的主要用途是 Java 项目,但没有任何关于它的 Java,而且它几乎可用于任何事情。

            使用非常简单,而且您也得到了很多社区支持。它非常擅长按照您的要求做事。

            至于代码中的全局选项,我认为它们是非常必要和有用的。但是,不要滥用它们。

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-03-02
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-22
            • 1970-01-01
            • 1970-01-01
            • 2022-08-19
            相关资源
            最近更新 更多