如何处理命令行选项和配置文件?

13

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

我正在寻找一些可以从命令行和/或配置文件中读取用户定义的选项的工具。

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

我知道有boost::program_options,但我无法适应其API。是否有轻量级的替代方案?

(顺便说一句,您是否会在代码中使用全局选项对象,以便可以从任何地方都能读取它?或者您认为那是一个邪恶的做法?)

9个回答

11

在 Google,我们使用 gflags。它不支持配置文件,但对于标识(flags),它比使用 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。此外,测试也有相当好的支持,因此单元测试可以独立设置不同的标志。


我喜欢!看起来非常易于使用。 - Milan

6

5

好的,你可能不会喜欢我的答案。我使用boost::program_options。这个接口需要一些时间来适应,但一旦你掌握了它,就会感觉非常棒。只是要确保进行大量的单元测试,因为如果语法错误,你将会得到运行时错误。

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


1
对于boost::program_options,我会给一个加分,但仅限于此!使用program options作为单例需要小心。我们曾经因为这样做而受到打击,现在需要为不同的文件添加不同的选项集。我们首先需要回去删除单例,以便为每个单独的文件存储不同的选项集。 - Richard Corden
好观点,Richard。我在游戏中使用boost::program_options,显然每个进程只需要一个选项集,但对于不同的目的来说,这将是一个坏主意。 - rlbond
你还支持boost::program_options吗?它似乎已经不再开发了(文档网站最后一次修改是在2004年)。它是否使用/兼容c++11?阅读你的帖子时,实际上并不是一个好的建议:只需确保进行大量单元测试,因为如果语法错误,您将获得运行时错误是一个很大的警告信号! - Walter

3

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

到目前为止,我很满意,并且可能会继续使用它,特别是因为它支持配置文件。 TCLAP是一个更复杂的库,但是ezOptionParser的简单性和额外功能非常令人信服。

其网站的其他优点包括(截至0.2.0):

  • 漂亮的解析输入以进行调试。
  • 自动创建使用消息,有三种布局(对齐、交错或错开)。
  • 单头文件实现。
  • 只依赖于STL。
  • 任意短和长选项名称(不需要破折号“ - ”或加号“ + ”前缀)。
  • 任意参数列表定界符。
  • 允许多个标志实例。
  • 验证必需选项、每个标志期望的参数数量、数据类型范围、用户定义的范围、列表成员和字符串列表的情况。
  • 可由字符串或常量定义验证条件。
  • 带注释的多文件导入。
  • 导出到文件,设置选项或所有选项,包括默认值(如果有)。
  • 选项解析索引用于顺序相关上下文。

2
我知道这是一个非常老的帖子,但只是为了避免其他人因阅读此帖子而陷入与我相同的陷阱。 ezOptionParser对于实际解析选项很有效,但它有一个致命的错误,如果您使用getUsage()函数来报告命令行选项,则会导致应用程序崩溃。该库现在不受作者支持,因此此错误将永远无法修复。请极度谨慎使用;或者更好的选择是使用其他东西。 - Graham

3
如果Boost对您来说过于复杂,GNU Gengetopt可能也是如此,但在我看来,这是一个有趣的工具可以用来玩耍。
此外,我尽量避免使用全局选项对象,我更喜欢每个类都读取自己的配置。除了整个“全局变量是邪恶的”哲学之外,将所有配置放在一个地方往往会变成一个不断增长的混乱,并且还更难以确定哪些配置变量正在使用。如果将配置保持靠近其使用位置,则更容易理解每个配置变量的作用,并更容易保持干净。
(至于我个人使用的是什么,最近一直使用的是一个专有的命令行解析库,是我公司的另一个人编写的,但不幸的是,这并没有帮助到你)

1

GNU getopt非常好用。如果你想要C++的感觉,可以考虑使用getoptpp,它是对原生getopt的封装。

至于配置文件,你应该尽量让它变得简单,以便于解析。如果你稍微考虑一下,你可能会想使用yaac&lex,但这对于小型应用来说可能会花费很多钱。

我还想建议你在应用程序中同时支持配置文件和命令行选项。配置文件适用于那些不经常更改的选项。命令行选项适用于当你想传递即时更改参数时(通常是在创建一个被其他程序调用的应用程序时)。


1

如果您正在使用Visual Studio 2005在x86和x64 Windows上工作,SimpleLibPlus library中有一些很好的命令行解析工具。我曾经使用过它并发现它非常有用。


0

对于命令行参数解析,我不太确定。在这个领域,我并没有需要非常丰富的功能,通常会自己编写代码以避免增加软件的依赖项。根据您的需求,您可能想要尝试这种方法或者不想尝试。我编写的C++程序通常不是从命令行调用的。

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


请访问pugixml.org,了解用C++编写的快速XML解析器。作为额外的奖励,它还支持XPath,并且也是仅有头文件的! - Sean

-4
尝试使用Apache Ant。它的主要用途是Java项目,但它与Java无关,几乎可用于任何事情。
使用相当简单,而且你也有很多社区支持。它非常擅长按照你所要求的方式完成任务。
至于代码中的全局选项,我认为它们非常必要和有用。不要滥用它们。

3
Apache Ant?构建工具?它与在C ++中读取命令行选项有什么关系? - Frank
你可以为C++保留一个基本的配置文件,但所有实际工作都可以通过Ant完成。请参阅http://www.codemesh.com/products/junction/doc/ant_cpp.html或只需访问http://www.google.com/search?hl=en&site=&q=using+ant+c%2B%2B&btnG=Search。 - Sudhir Jonathan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接