getopt 中的选项顺序问题

Issue with options order in getopt

我在使用 getopt 时遇到问题。在我的程序中,我希望 运行 具有以下选项的程序:-l -w -n -bnb 是可选的,但是程序必须具有 lw,而不是两者。此外,如果 w 被调用,它后面必须跟一个参数。另外,顺序应该是先lw,然后是nb,顺序无关紧要。

以下是有效参数的示例:

./prog -l -n -b
./prog -w argument -b -n
./prog -l -n
./prog -l -b

这些例子无效:

./prog -l -w argument
./prog -n -l
./prog -b -l

基于这些要求,我在使用 getopt 时遇到了问题。当然,我可以使用无数的 if else 语句,但这会很丑陋并且不必要地复杂。

具体来说,我在参数的顺序和使 -l-w 选项成为非此即彼的关系时遇到了问题。

这是我目前所知道的,尽管由于这些不确定因素并不多。

while ((option = getopt(argc, argv,"lw:nb:")) != -1) {
  switch(option) {
  case'l': ...  // I haven't wrote anything here yet
  case'w': ...
  case'n': ...
  case'b': ...
  case '?': ...
  default: ...
  }
}

首先,getopt 确保 w 有参数。这就是重点 : 在您的 getopt 字符串中。如果 -b 不需要参数,那么你应该删除它后面的 :

其次,我不认为验证参数条件有你想的那么糟糕 这将是。你应该已经有变量来跟踪你的 选项,像这样:

int opt_l = 0;
int opt_w = 0;
char *arg_w = 0;
int opt_n = 0;
int opt_b = 0;

你还应该有一个打印出用法和有用错误的函数 给用户的消息,如下所示:

int exit_usage(const char *err)
{
    if( err ) { printf("Bad arguments: %s\n", err); }
    printf("Usage: ...\n");
    exit(1);
}

然后这是一个简单的单行检查来验证您的先决条件。如果一个 前提条件失败,然后打印错误并向您的用户显示使用信息。 您不必将先决条件检查塞进一行,但它往往 当每行都是一行时,更容易阅读先决条件列表。 像这样:

while ((option = getopt(argc, argv, "lw:nb")) != -1)
{
    switch(option)
    {
    case 'l':
        if( opt_w != 0 ) { exit_usage("Cannot combine -l with -w"); }
        ++opt_l;
        break;
    case 'w':
        if( opt_l != 0 ) { exit_usage("Cannot combine -l with -w"); }
        arg_w = optarg;
        ++opt_w;
        break;
    case 'n':
        if( opt_l == 0 && opt_w == 0 ) { exit_usage("-n requires -l or -w first"); }
        ++opt_n;
        break;
    case 'b':
        if( opt_l == 0 && opt_w == 0 ) { exit_usage("-n requires -l or -w first"); }
        ++opt_b;
        break;
    case '?':
        exit_usage(NULL);
        break;
    default:
        break;
    }
}