getopt 中的选项顺序问题
Issue with options order in getopt
我在使用 getopt
时遇到问题。在我的程序中,我希望 运行 具有以下选项的程序:-l -w -n -b
。 n
和 b
是可选的,但是程序必须具有 l
或 w
,而不是两者。此外,如果 w
被调用,它后面必须跟一个参数。另外,顺序应该是先l
或w
,然后是n
或b
,顺序无关紧要。
以下是有效参数的示例:
./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;
}
}
我在使用 getopt
时遇到问题。在我的程序中,我希望 运行 具有以下选项的程序:-l -w -n -b
。 n
和 b
是可选的,但是程序必须具有 l
或 w
,而不是两者。此外,如果 w
被调用,它后面必须跟一个参数。另外,顺序应该是先l
或w
,然后是n
或b
,顺序无关紧要。
以下是有效参数的示例:
./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;
}
}