#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
/* Flag set by ‘--verbose’. */
static int verbose_flag;
int
main (int argc, char **argv)
{
int c;
while (1)
{
static struct option long_options[] =
{
/* These options set a flag. */
{"verbose", no_argument, &verbose_flag, 1},
{"brief", no_argument, &verbose_flag, 0},
/* These options don’t set a flag.
We distinguish them by their indices. */
{"add", no_argument, 0, 'a'},
{"append", no_argument, 0, 'b'},
{"delete", required_argument, 0, 'd'},
{"create", required_argument, 0, 'c'},
{"file", required_argument, 0, 'f'},
{0, 0, 0, 0}
};
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long (argc, argv, "abc:d:f:",
long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
switch (c)
{
case 0:
/* If this option set a flag, do nothing else now. */
if (long_options[option_index].flag != 0)
break;
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case 'a':
puts ("option -a\n");
break;
什么样的选项可以使程序到达case 0
和
printf("option %s", long_options[option_index].name);
是一个长期选项,其标志未设置,还是一个长期选项,其中&#34; val&#34;碰巧是0
?
什么样的选择&#34; {0,0,0,0}&#34;指定?
答案 0 :(得分:1)
如果该选项设置了一个标志,即.flag
不是一个空指针,getopt_long()
returns 0
:
如果flag不是空指针,则表示此选项应该设置 该计划中的一面旗帜。标志是你的int类型的变量 限定。将标志的地址放在标志字段中。放入val 字段您希望此选项存储在标志中的值。在 在这种情况下,getopt_long返回0。
示例代码在此处没有使用仅设置标志的选项;这种可能性稍后在example program中处理:
/* Instead of reporting ‘--verbose’
and ‘--brief’ as they are encountered,
we report the final status resulting from them. */
if (verbose_flag)
puts ("verbose flag is set");
{0, 0, 0, 0}
仅仅是一个哨兵,因为option
结构数组必须终止&#34;一个包含全零的元素。&#34;
在{ 0, 0, 0, 0 }
内部使用全零(getopt_long()
)元素来确定何时到达option
结构数组的末尾。发生这种情况时,返回值-1
。示例代码中的while(1)
循环首先检查这个循环,并在这种情况下终止循环:
/* Detect the end of the options. */
if (c == -1)
break;
哪种选项可以让计划覆盖
case 0
和printf("option %s", long_options[option_index].name);
?
如果选项的.val
字段恰好包含0
,那么作为空指针的.flag
将导致getopt_long()
返回此值({{1 }})。 0
中第一个if
语句后面的代码检查这种可能性。这可能意味着在此示例代码中说明来自case 0
的{{1}}的返回值本身可能不表示已设置标志。但这是一种特殊情况,示例中的数组元素不会导致达到0
语句。这甚至可以被视为堕落的情况;最好避免在选项的getopt_long()
字段中使用printf()
,并避免在此处完全指定数值,以支持使用字符常量的约定,如示例中所做。如果采用此约定,则需要0
字段中的.val
值才能触发此行为。
答案 1 :(得分:1)
当flag
中的struct option
字段为非NULL时,getopt_long
将为该选项返回0,并且val
字段的值存储在该地址中在flag
中给出。
所以在上面的例子中,当&#34; verbose&#34;选项被给出,getopt_long
将返回0并且verbose_flag
被设置为1.类似地,对于&#34;简要说明&#34;选项,getopt_long
将返回0,verbose_flag
将设置为0.
数组末尾的所有字段设置为零的选项是一个标志,指示选项列表的结尾,而不是传入数组的长度。因为全零元素只是数组结束指示符而不是真正的选项,所以不需要处理它。
声明的
longopts
是指向作为struct option
数组的第一个元素的指针struct option { const char *name; int has_arg; int *flag; int val; };
不同领域的含义是:
名称
是长选项的名称。
has_arg
是:
no_argument
(或0)如果选项没有参数;required_argument
(或1)如果选项需要参数;要么optional_argument
(或2)如果选项采用可选参数。标志
指定如何为long选项返回结果。如果flag为NULL, 然后getopt_long()返回val。 (例如,呼叫程序可以 将val设置为等效的短选项字符。)否则, getopt_long()返回0,标志指向一个设置为的变量 val如果找到该选项,但如果该选项不是,则保持不变 找到。强>
VAL
是要返回的值,要么加载到指向的变量中 旗。
数组的最后一个元素必须用零填充。
关于什么类型的选项将超过break
并在printf
中调用case 0:
,flag
的选项为0(或NULL),0为{ {1}},非空val
将落在此处,即name
。列表中没有这样的选项,因此代码不会被执行,但无论如何它可能都包含在对未来代码的安全检查中,可能会做类似的事情。