English 中文(简体)
在C ++中处理命令行参数的最有效方法[重复]
原标题:
  • 时间:2009-05-14 20:46:44
  •  标签:
Closed. This question needs to be more focused. It is not currently accepting answers.
Closed 2 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.

如果指定程序如此运行,C ++中解析命令行参数的最佳方法是什么:

prog [-abc] [input [output]]

有没有内置在标准库中的方法可以完成这个,还是我需要编写自己的代码?


相关的:

最佳回答

Boost.Program_options 应该可以解决问题。

问题回答

对于boost::program_options和GNU getopt的建议是很好的。

然而,对于简单的命令行选项,我倾向于使用std :: find

例如,在-f命令行参数之后读取文件名称。您也可以仅检测是否传递了单词选项,如-h以获取帮助。

#include <algorithm>

char* getCmdOption(char ** begin, char ** end, const std::string & option)
{
    char ** itr = std::find(begin, end, option);
    if (itr != end && ++itr != end)
    {
        return *itr;
    }
    return 0;
}

bool cmdOptionExists(char** begin, char** end, const std::string& option)
{
    return std::find(begin, end, option) != end;
}

int main(int argc, char * argv[])
{
    if(cmdOptionExists(argv, argv+argc, "-h"))
    {
        // Do stuff
    }

    char * filename = getCmdOption(argv, argv + argc, "-f");

    if (filename)
    {
        // Do interesting things
        // ...
    }

    return 0;
}

使用此方法时要注意,必须将std::strings用作std::find的值,否则等式检查将在指针值上执行。


我希望编辑此回复而不是添加新的回复,因为它基于原始回答。我稍微重写了函数并将它们封装在一个类中,所以这是代码。我认为这样使用可能是实用的:

class InputParser{
    public:
        InputParser (int &argc, char **argv){
            for (int i=1; i < argc; ++i)
                this->tokens.push_back(std::string(argv[i]));
        }
        /// @author iain
        const std::string& getCmdOption(const std::string &option) const{
            std::vector<std::string>::const_iterator itr;
            itr =  std::find(this->tokens.begin(), this->tokens.end(), option);
            if (itr != this->tokens.end() && ++itr != this->tokens.end()){
                return *itr;
            }
            static const std::string empty_string("");
            return empty_string;
        }
        /// @author iain
        bool cmdOptionExists(const std::string &option) const{
            return std::find(this->tokens.begin(), this->tokens.end(), option)
                   != this->tokens.end();
        }
    private:
        std::vector <std::string> tokens;
};

int main(int argc, char **argv){
    InputParser input(argc, argv);
    if(input.cmdOptionExists("-h")){
        // Do stuff
    }
    const std::string &filename = input.getCmdOption("-f");
    if (!filename.empty()){
        // Do interesting things ...
    }
    return 0;
}

我可以建议使用Templatized C++命令行解析库(GitHub上有一些分支可用),其API非常简单直接(从网站引用):

the library is implemented entirely in header files making it easy to use and distribute with other software. It is licensed under the MIT License for worry free distribution.

这是手册中的一个示例,这里为了简单使用色彩。

#include <string>
#include <iostream>
#include <algorithm>
#include <tclap/CmdLine.h>

int main(int argc, char** argv)
{

    // Wrap everything in a try block.  Do this every time,
    // because exceptions will be thrown for problems.
    try {

    // Define the command line object, and insert a message
    // that describes the program. The "Command description message"
    // is printed last in the help text. The second argument is the
    // delimiter (usually space) and the last one is the version number.
    // The CmdLine object parses the argv array based on the Arg objects
    // that it contains.
    TCLAP::CmdLine cmd("Command description message",    , "0.9");

    // Define a value argument and add it to the command line.
    // A value arg defines a flag and a type of value that it expects,
    // such as "-n Bishop".
    TCLAP::ValueArg<std::string> nameArg("n","name","Name to print",true,"homer","string");

    // Add the argument nameArg to the CmdLine object. The CmdLine object
    // uses this Arg to parse the command line.
    cmd.add( nameArg );

    // Define a switch and add it to the command line.
    // A switch arg is a boolean argument and only defines a flag that
    // indicates true or false.  In this example the SwitchArg adds itself
    // to the CmdLine object as part of the constructor.  This eliminates
    // the need to call the cmd.add() method.  All args have support in
    // their constructors to add themselves directly to the CmdLine object.
    // It doesn t matter which idiom you choose, they accomplish the same thing.
    TCLAP::SwitchArg reverseSwitch("r","reverse","Print name backwards", cmd, false);

    // Parse the argv array.
    cmd.parse( argc, argv );

    // Get the value parsed by each arg.
    std::string name = nameArg.getValue();
    bool reverseName = reverseSwitch.getValue();

    // Do what you intend.
    if ( reverseName )
    {
            std::reverse(name.begin(),name.end());
            std::cout << "My name (spelled backwards) is: " << name << std::endl;
    }
    else
            std::cout << "My name is: " << name << std::endl;


    } catch (TCLAP::ArgException &e)  // catch any exceptions
    { std::cerr << "error: " << e.error() << " for arg " << e.argId() << std::endl; }
}

您可以使用GNU GetOpt(LGPL)或其中一种各种C++端口,例如getoptpp(GPL)。

一个使用 GetOpt 的简单示例,你想要的是 (prog [-ab] input),示例如下:

// C Libraries:
#include <string>
#include <iostream>
#include <unistd.h>

// Namespaces:
using namespace std;

int main(int argc, char** argv) {
    int opt;
    string input = "";
    bool flagA = false;
    bool flagB = false;

    // Retrieve the (non-option) argument:
    if ( (argc <= 1) || (argv[argc-1] == NULL) || (argv[argc-1][0] ==  - ) ) {  // there is NO input...
        cerr << "No argument provided!" << endl;
        //return 1;
    }
    else {  // there is an input...
        input = argv[argc-1];
    }

    // Debug:
    cout << "input = " << input << endl;

    // Shut GetOpt error messages down (return  ? ): 
    opterr = 0;

    // Retrieve the options:
    while ( (opt = getopt(argc, argv, "ab")) != -1 ) {  // for each option...
        switch ( opt ) {
            case  a :
                    flagA = true;
                break;
            case  b :
                    flagB = true;
                break;
            case  ? :  // unknown option...
                    cerr << "Unknown option:  " << char(optopt) << " !" << endl;
                break;
        }
    }

    // Debug:
    cout << "flagA = " << flagA << endl;
    cout << "flagB = " << flagB << endl;

    return 0;
}

GNU GetOpt (GNU获取选项)。

一个使用 GetOpt 的简单例子:

// C/C++ Libraries:
#include <string>
#include <iostream>
#include <unistd.h>

// Namespaces:
using namespace std;

int main(int argc, char** argv) {
    int opt;
    bool flagA = false;
    bool flagB = false;

    // Shut GetOpt error messages down (return  ? ): 
    opterr = 0;

    // Retrieve the options:
    while ( (opt = getopt(argc, argv, "ab")) != -1 ) {  // for each option...
        switch ( opt ) {
            case  a :
                    flagA = true;
                break;
            case  b :
                    flagB = true;
                break;
            case  ? :  // unknown option...
                    cerr << "Unknown option:  " << char(optopt) << " !" << endl;
                break;
        }
    }

    // Debug:
    cout << "flagA = " << flagA << endl;
    cout << "flagB = " << flagB << endl;

    return 0;
}

如果您有需要选项的参数,也可以使用optarg

另一种选择是精简的C++选项解析器:

将此翻译为中文:http://optionparser.sourceforge.net http://optionparser.sourceforge.net

It is a header-only library (just a single header file, in fact) and: 和 (hé) unlike all the other suggestions it is also freestand: 和 (hé)ing, i.e. it has no dependencies whatsoever. In particular there s no dependency on the STL. It does not even use exceptions or anything else that requires library support. This means it can be linked with plain C or other languages without introducing "foreign" libraries.

Like boost::program_options its API offers convenient direct access to options, i.e. you can write code like this

如果(选项[帮助])…;

and: 和 (hé)

int verbosity = options[VERBOSE].count(); 详细程度 = options[VERBOSE].count();

与boost::program_options不同,这只是使用一个由(用户提供的)枚举索引的数组。这提供了一个方便的关联容器,但没有重量。

It s well documented and: 和 (hé) has a company-friendly license (MIT).

TLMC++OP includes a nice formatter for usage messages that can do line-wrapping and: 和 (hé) column alignment which is useful if you re localizing your program, because it ensures that the output will look good even in languages that have longer messages. It also saves you the nuisance of manually formatting your usage for 80 columns.

for (int i = 1; i < argc; i++) {

    if (strcmp(argv[i],"-i")==0) {
        filename = argv[i+1];
        printf("filename: %s",filename);
    } else if (strcmp(argv[i],"-c")==0) {
        convergence = atoi(argv[i + 1]);
        printf("
convergence: %d",convergence);
    } else if (strcmp(argv[i],"-a")==0) {
        accuracy = atoi(argv[i + 1]);
        printf("
accuracy:%d",accuracy);
    } else if (strcmp(argv[i],"-t")==0) {
        targetBitRate = atof(argv[i + 1]);
        printf("
targetBitRate:%f",targetBitRate);
    } else if (strcmp(argv[i],"-f")==0) {
        frameRate = atoi(argv[i + 1]);
        printf("
frameRate:%d",frameRate);
    }

}

TCLAP is a really nice lightweight design and easy to use: http://tclap.sourceforge.net/

你可能想使用外部库来完成此任务。有许多选择。

Boost拥有一个非常丰富的(像往常一样)库Boost Program Options

我的个人最爱,过去几年一直是 TCLAP —— 完全是模板化的,因此没有库或链接,自动化--help 生成和其他好处。请参见文档中的最简单的示例

我发现使用ezOptionParser更容易。它也是一个单一头文件,除了STL以外没有依赖项,适用于Windows和Linux(很可能还有其他平台),由于示例没有学习曲线,具有其他库没有的功能(如带注释的文件导入/导出、带限定符的任意选项名称、自动使用格式等),并且使用LGPL许可证。

如果您只想自己处理命令行选项,则最简单的方法是放置:

vector<string> args(argv + 1, argv + argc);

在你的main()的顶部。这将把所有的命令行参数复制到一个std::string的向量中。然后你可以使用==来轻松比较字符串,而不是不断地调用strcmp()。例如:

int main(int argc, char **argv) {
    vector<string> args(argv + 1, argv + argc);
    string infname, outfname;

    // Loop over command-line args
    // (Actually I usually use an ordinary integer loop variable and compare
    // args[i] instead of *i -- don t tell anyone! ;)
    for (auto i = args.begin(); i != args.end(); ++i) {
        if (*i == "-h" || *i == "--help") {
            cout << "Syntax: foomatic -i <infile> -o <outfile>" << endl;
            return 0;
        } else if (*i == "-i") {
            infname = *++i;
        } else if (*i == "-o") {
            outfname = *++i;
        }
    }
}

<强>[编辑:我意识到我正在将程序的名称 argv [0] 复制到 args 中 - 已更正。]

这里有一个可用的Google库

实际上,命令行解析已经“解决”了。只需选择一个。

在C++中,答案通常是在Boost中...

Boost程序选项

尝试使用Boost::Program Options。它允许您读取和解析命令行以及配置文件。

我认为GNU GetOpt不太容易使用。

Qt和Boost可能是一个解决方案,但您需要下载和编译大量代码。

所以我自己实现了一个解析器,它可以生成参数的std :: map

例如,打电话:

 ./myProgram -v -p 1234

地图将是:

 ["-v"][""]
 ["-p"]["1234"]

用法是:

int main(int argc, char *argv[]) {
    MainOptions mo(argc, argv);
    MainOptions::Option* opt = mo.getParamFromKey("-p");
    const string type = opt ? (*opt).second : "";
    cout << type << endl; /* Prints 1234 */
    /* Your check code */
}

主要选项.h

#ifndef MAINOPTIONS_H_
#define MAINOPTIONS_H_

#include <map>
#include <string>

class MainOptions {
public:
    typedef std::pair<std::string, std::string> Option;
    MainOptions(int argc, char *argv[]);
    virtual ~MainOptions();
    std::string getAppName() const;
    bool hasKey(const std::string&) const;
    Option* getParamFromKey(const std::string&) const;
    void printOptions() const;
private:
    typedef std::map<std::string, std::string> Options;
    void parse();
    const char* const *begin() const;
    const char* const *end() const;
    const char* const *last() const;
    Options options_;
    int argc_;
    char** argv_;
    std::string appName_;
};

主要选项.cpp

#include "MainOptions.h"

#include <iostream>

using namespace std;

MainOptions::MainOptions(int argc, char* argv[]) :
        argc_(argc),
        argv_(argv) {
    appName_ = argv_[0];
    this->parse();
}

MainOptions::~MainOptions() {
}

std::string MainOptions::getAppName() const {
    return appName_;
}

void MainOptions::parse() {
    typedef pair<string, string> Option;
    Option* option = new pair<string, string>();
    for (const char* const * i = this->begin() + 1; i != this->end(); i++) {
        const string p = *i;
        if (option->first == "" && p[0] ==  - ) {
            option->first = p;
            if (i == this->last()) {
                options_.insert(Option(option->first, option->second));
            }
            continue;
        } else if (option->first != "" && p[0] ==  - ) {
            option->second = "null"; /* or leave empty? */
            options_.insert(Option(option->first, option->second));
            option->first = p;
            option->second = "";
            if (i == this->last()) {
                options_.insert(Option(option->first, option->second));
            }
            continue;
        } else if (option->first != "") {
            option->second = p;
            options_.insert(Option(option->first, option->second));
            option->first = "";
            option->second = "";
            continue;
        }
    }
}

void MainOptions::printOptions() const {
    std::map<std::string, std::string>::const_iterator m = options_.begin();
    int i = 0;
    if (options_.empty()) {
        cout << "No parameters
";
    }
    for (; m != options_.end(); m++, ++i) {
        cout << "Parameter [" << i << "] [" << (*m).first << " " << (*m).second
                << "]
";
    }
}

const char* const *MainOptions::begin() const {
    return argv_;
}

const char* const *MainOptions::end() const {
    return argv_ + argc_;
}

const char* const *MainOptions::last() const {
    return argv_ + argc_ - 1;
}

bool MainOptions::hasKey(const std::string& key) const {
    return options_.find(key) != options_.end();
}

MainOptions::Option* MainOptions::getParamFromKey(
        const std::string& key) const {
    const Options::const_iterator i = options_.find(key);
    MainOptions::Option* o = 0;
    if (i != options_.end()) {
        o = new MainOptions::Option((*i).first, (*i).second);
    }
    return o;
}

GNU C库中包括这些工具,其中包括GetOpt。

如果你在使用Qt并喜欢GetOpt接口,froglogic这里发布了一个不错的接口。

如果可以的话,我想要吹嘘一下自己,同时我也想建议看一下我写的选项解析库:dropt

  • It s a C library (with a C++ wrapper if desired).
  • It s lightweight.
  • It s extensible (custom argument types can be easily added and have equal footing with built-in argument types).
  • It should be very portable (it s written in standard C) with no dependencies (other than the C standard library).
  • It has a very unrestrictive license (zlib/libpng).

它提供的一个特性,而许多其他软件都没有的是能够覆盖先前的选项。例如,如果你有一个 shell 别名:

alias bar="foo --flag1 --flag2 --flag3"

你想使用 bar 但是带有 --flag1 禁用,它允许你这样做:

bar --flag1=0

我喜欢C的getopt(),但我已经老了。 :-)

Google的gflags

我建议使用一个库。经典而可信赖的getopt和其他的库肯定也有。

有许多好的图书馆可供选择。

Boost程序选项是一种相当沉重的解决方案,因为将其添加到您的项目中需要您构建Boost,并且语法有点令人困惑(在我看来)。不过,它可以做几乎所有的事情,包括让命令行选项覆盖配置文件中设置的选项。

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

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

AnyOption是一个用于容易解析复杂命令行选项的C++类。它还可以解析以选项值对格式存储的资源文件中的选项。

AnyOption 实施传统的 POSIX 风格字符选项(-n),以及较新的 GNU 风格长选项(--name)。或者,您可以要求忽略 POSIX 风格选项并使用更简单的长选项版本(-name)。

Qt 5.2带有一个命令行解析器API

小例子:

#include <QCoreApplication>
#include <QCommandLineParser>
#include <QDebug>

int main(int argc, char **argv)
{
  QCoreApplication app(argc, argv);
  app.setApplicationName("ToolX");
  app.setApplicationVersion("1.2");

  QCommandLineParser parser;
  parser.setApplicationDescription("Tool for doing X.");
  parser.addHelpOption();
  parser.addVersionOption();
  parser.addPositionalArgument("infile",
      QCoreApplication::translate("main", "Input file."));

  QCommandLineOption verbose_opt("+",
      QCoreApplication::translate("main", "be verbose"));
  parser.addOption(verbose_opt);

  QCommandLineOption out_opt(QStringList() << "o" << "output",
      QCoreApplication::translate("main", "Output file."),
      QCoreApplication::translate("main", "filename"), // value name
      QCoreApplication::translate("main", "out")   // default value
      );
  parser.addOption(out_opt);

  // exits on error
  parser.process(app);

  const QStringList args = parser.positionalArguments();

  qDebug() << "Input files: " << args
    << ", verbose: " << parser.isSet(verbose_opt)
    << ", output: " << parser.value(out_opt)
    <<  
 ;
  return 0;
}

Example output

自动生成的帮助屏幕:

$ ./qtopt -h
Usage: ./qtopt [options] infile
Tool for doing X.

Options:
  -h, --help               Displays this help.
  -v, --version            Displays version information.
  -+                       be verbose
  -o, --output   Output file.

Arguments:
  infile                   Input file.

自动生成的版本输出:

$ ./qtopt -v
ToolX 1.2

一些真实电话:

$ ./qtopt b1 -+ -o tmp blah.foo
Input files:  ("b1", "blah.foo") , verbose:  true , output:  "tmp"
$ ./qtopt          
Input files:  () , verbose:  false , output:  "out"

一个解析错误:

$ ./qtopt --hlp
Unknown option  hlp .
$ echo $?
1

Conclusion

如果您的程序已经使用了Qt(>= 5.2)的库,那么它的命令行解析API已经足够方便来完成工作了。

请注意,在选项解析器运行之前,QApplication 已使用了内置的 Qt 选项。

一个命令基本上是一个字符串。一般来说,它可以分成两个部分 - 命令的名称 name 和命令的参数 arguments

例子:

ls

用于列出目录内容的是:

user@computer:~$ ls
Documents Pictures Videos ...

上面的ls是在用户的home文件夹中执行的。这里要列出哪个文件夹的参数隐式添加到命令中。我们可以显式地传递一些参数:

user@computer:~$ ls Picture
image1.jpg image2.jpg ...

在这里,我明确告诉了ls我想要查看哪个文件夹的内容。我们可以使用另一个参数,例如l,列出每个文件和文件夹的详细信息,如访问权限、大小等:

user@computer:~$ ls Pictures
-rw-r--r-- 1 user user   215867 Oct 12  2014 image1.jpg
-rw-r--r-- 1 user user   268800 Jul 31  2014 image2.jpg
...

哦,这个尺寸看起来很奇怪(215867,268800)。让我们添加'h'标记以获得更人性化的输出:

user@computer:~$ ls -l -h Pictures
-rw-r--r-- 1 user user  211K Oct 12  2014 image1.jpg
-rw-r--r-- 1 user user  263K Jul 31  2014 image2.jpg
...

有些命令允许它们的参数组合在一起(在上面的例子中,我们也可以写成ls -lh,并得到相同的输出),使用短的(通常是一个字母,但有时更多;缩写)或长的名称(在ls的情况下,我们有-a--all用于列出包括隐藏文件在内的所有文件,其中--all-a的长名称)等等。有些命令的参数顺序非常重要,但也有其他命令的参数顺序完全不重要

例如,使用ls -lhls -hl并不重要,但是在mv(移动/重命名文件)中,您对最后2个参数即mv [OPTIONS] SOURCE DESTINATION的灵活性较小。

为了掌握命令及其参数,您可以使用man(例如:man ls)或info(例如:info ls)。

在许多编程语言中,包括C/C++,您都有一种解析用户附加到可执行文件调用(命令)的命令行参数的方法。此外,还提供了许多库来执行此任务,因为在其核心中,正确地执行这项任务并同时提供大量参数及其变体实际上并不容易。

  • getopt
  • argp_parse
  • gflags
  • ...

每个C/C++应用程序都有所谓的入口点,基本上是您的代码开始的地方 - main函数:

int main (int argc, char *argv[]) { // When you launch your application the first line of code that is ran is this one - entry point
    // Some code here
    return 0; // Exit code of the application - exit point
}

无论您是否使用图书馆(如上述我提到的其中之一;但这在您的情况下显然不被允许;))或自行完成,您的

函数都有两个参数:

  • argc - represents the number of arguments
  • argv - a pointer to an array of strings (you can also see char** argv which is basically the same but more difficult to use).

注意:实际上,main也有第三个参数char *envp [],它允许将环境变量传递给您的命令,但这是一件更高级的事情,我真的不认为在您的情况下是必需的。

命令行参数的处理分为两个部分:

  1. Tokenizing - this is the part where each argument gets a meaning. Its the process of breaking your arguments list into meaningful elements (tokens). In the case of ls -l the l is not only a valid character but also a token in itself since it represents a complete, valid argument.

以下是输出参数个数和(未经验证有效性的)可能是参数的字符的示例:

#include <iostream>
using std::cout;
using std::endl;

int main (int argc, char *argv[]) {
    cout << "Arguments  count=%d" << argc << endl;

    // First argument is ALWAYS the command itself
    cout << "Command: " << argv[0] << endl;

    // For additional arguments we start from argv[1] and continue (if any)
    for (int i = 1; i < argc; i++) {
        cout << "arg[" << i << "]: " << argv[i] << endl;
    }

    cout << endl;
    return 0;
}
  1. “解析”-获得标记(参数及其值)后,您需要检查您的命令是否支持这些标记。例如:

    user@computer:~$ ls -y
    

    会返回

    ls: invalid option --  y 
    Try  ls --help  for more information.
    

    这是因为解析失败了。为什么?因为y (以及分别的-y; 注意---:等不是必需的,由解析参数决定是否需要这些内容;在Unix / Linux系统中,这是一种约定,但您不必遵守)是ls命令的未知参数。

对于每个参数(如果成功识别),您会在应用程序中触发某种变化。例如,您可以使用if-else来检查某个参数是否有效以及它的功能,然后更改您想要更改执行其余代码时该参数更改的任何内容。您可以使用旧的C风格或C++风格:

* `if (strcmp(argv[1], "x") == 0) { ... }` - compare the pointer value
* `if (std::string(argv[1]) == "x") { ... }` - convert to string and then compare

我实际上喜欢(在不使用库时)将`argv`转换为一个字符串`std::vector`,像这样:

std::vector<std::string> args(argv, argv+argc);
for (size_t i = 1; i < args.size(); ++i) {
    if (args[i] == "x") {
        // Handle x
    }
    else if (args[i] == "y") {
        // Handle y
    }
    // ...
}

std::vector<std::string> args(argv, argv+argc); 部分只是一种更简单的 C++ 风格来处理字符串数组的方法,因为 char * 是 C 风格的字符串(使用 char *argv[] 表示一个这样的字符串数组),可以很容易地转换为 C++ 的字符串,即 std::string。然后我们可以通过给出 argv 的起始地址,再指向它的最后地址,也就是 argv + argc (我们将 argc 个字符串添加到 argv 的基址上,这基本上是指向我们数组的最后一个地址)来将所有转换后的字符串添加到向量中。

在上面的 for 循环中,您可以看到我使用简单的 if-else 检查某个参数是否可用,如果是,则相应地处理它。注意:使用这样的循环,参数的顺序并不重要。正如我在开始时提到的,有些命令实际上对于一些或所有参数都有严格的顺序。您可以通过手动调用每个 args (或 argv 如果您使用最初的 char * argv [] 而不是向量解决方案)来处理这个问题:

// No for loop!
if (args[1] == "x") {
    // Handle x
}
else if (args[2] == "y") {
    // Handle y
}
// ...

这可以确保在1位置只能期望x等等。问题在于,通过索引超出范围,可能会使自己违反规则,因此必须确保索引保持在argc设置的范围内:

if (argc > 1 && argc <= 3) {
    if (args[1] == "x") {
        // Handle x
    }
    else if (args[2] == "y") {
        // Handle y
    }
}

上面的示例确保您在索引12处拥有内容,但不超过此范围。

最后但并非最不重要的,每个参数的处理完全取决于您。您可以使用布尔标志,在检测到某个参数时设置它们(例如:if(args [i] ==“x”){xFound = true;} ),然后在您的代码中根据bool xFound及其值执行某些操作),如果参数是数字或包含数字以及参数名称,则可以使用数字类型(例如:mycommand -x = 4 具有参数 -x = 4 ,您还可以解析x4,最后的值是x )等。根据手头的任务,您可以疯狂地添加无数的复杂性到命令行参数中。

希望这有所帮助。如果有什么不清楚或您需要更多的例子,请让我知道。

如果您可以使用 Boost 库,我建议使用 boost::program_options。

STL和常规的C++/C运行时库中没有特定的内容。

argstreamboost.program_option非常相似:它允许将变量绑定到选项等。但是它不处理存储在配置文件中的选项。

你可以使用已经创建好的库来完成这个。

将此翻译为中文:http://www.boost.org/doc/libs/1_44_0/doc/html/program_options.html

尝试使用CLPP库。它是一个简单而灵活的命令行参数解析库。仅有头文件,支持跨平台。只使用ISO C++和Boost C++库。在我看来,比Boost.Program_options更容易使用。

图书馆:http://sourceforge.net/projects/clp-parser/

2010年10月26日-新版本2.0rc发布。修复了许多漏洞,源代码进行了全面的重构,文档、示例和注释已经得到了更正。





相关问题