如果程序被指定像这样运行,那么在c++中解析命令行参数的最佳方式是什么:

prog [-abc] [input [output]]

是否有某种方法可以在标准库中实现这一点,或者我需要自己编写代码?


相关:

在unicode c++应用程序中解析命令行参数


当前回答

我建议你去图书馆。有经典而古老的getopt,我相信还有其他的。

其他回答

有很多好的库可用。

Boost Program Options是一个相当重量级的解决方案,因为将它添加到项目中需要构建Boost,而且语法有点令人困惑(在我看来)。但是,它几乎可以做任何事情,包括让命令行选项覆盖配置文件中设置的选项。

SimpleOpt是一个相当全面但简单的命令行处理器。它是一个单一的文件,具有简单的结构,但只处理将命令行解析为选项,您必须进行所有的类型和范围检查。它适用于Windows和Unix,并且还附带了一个适用于Windows的glob版本。

getopt在Windows上可用。它与Unix机器上的相同,但它通常是一个GPL库。

我建议你去图书馆。有经典而古老的getopt,我相信还有其他的。

一个简单的解决方案是将argv放入std::map中,以便查找:

map<string, string> argvToMap(int argc, char * argv[])
{
    map<string, string> args;

    for(int i=1; i<argc; i++) {
        if (argv[i][0] == '-') {
            const string key = argv[i];
            string value = "";
            if (i+1 < argc && argv[i+1][0] != '-') {
                value = string(argv[i+1]);
                i++;
            }

            args[key] = value;
        }
    }

    return args;
}

使用示例:

#include <map>
#include <string>
#include <iostream>

using namespace std;

map<string, string> argvToMap(int argc, char * argv[])
{
    map<string, string> args;

    for(int i=1; i<argc; i++) {
        if (argv[i][0] == '-') {
            const string key = argv[i];
            string value = "";
            if (i+1 < argc && argv[i+1][0] != '-') {
                value = string(argv[i+1]);
                i++;
            }

            args[key] = value;
        }
    }

    return args;
}

void printUsage()
{
    cout << "simple_args: A sample program for simple arg parsing\n"
            "\n"
            "Example usage:\n"
            "    ./simple_args --print-all --option 1 --flag 2\n";
}

int main(int argc, char * argv[])
{
    auto args = argvToMap(argc, argv);

    if (args.count("-h") || args.count("--help")) {
        printUsage();
    }
    else if (args.count("--print-all")) {
        for (auto const & pair: args)
            cout << "{" << pair.first << ": " << pair.second << "}\n";
    }

    return 0;
}

输出:

$ ./simple_args --print-all --option 1 --flag "hello world"
{--flag: hello world}
{--option: 1}
{--print-all: }

这种方法肯定有很大的局限性,但我发现它很好地平衡了简单性和实用性。

提高program_options。

如果你可以使用boost库,我推荐boost::program_options。

在STL和常规的c++ /C运行时库中都没有特定的东西。