C 使用“getopt”long时理解“option long\u options[]”`
我正在努力学习使用C 使用“getopt”long时理解“option long\u options[]”`,c,parameter-passing,command-line-arguments,getopt,getopt-long,C,Parameter Passing,Command Line Arguments,Getopt,Getopt Long,我正在努力学习使用getopt\u long。从中,我看到了代码 #include <stdio.h> /* for printf */ #include <stdlib.h> /* for exit */ #include <getopt.h> /* for getopt_long; POSIX standard getopt is in unistd.h */ int main (int argc, char **argv) {
getopt\u long
。从中,我看到了代码
#include <stdio.h> /* for printf */
#include <stdlib.h> /* for exit */
#include <getopt.h> /* for getopt_long; POSIX standard getopt is in unistd.h */
int main (int argc, char **argv) {
int c;
int digit_optind = 0;
int aopt = 0, bopt = 0;
char *copt = 0, *dopt = 0;
static struct option long_options[] = {
{"add", 1, 0, 0},
{"append", 0, 0, 0},
{"delete", 1, 0, 0},
{"verbose", 0, 0, 0},
{"create", 1, 0, 'c'},
{"file", 1, 0, 0},
{NULL, 0, NULL, 0}
};
int option_index = 0;
while ((c = getopt_long(argc, argv, "abc:d:012",
long_options, &option_index)) != -1) {
int this_option_optind = optind ? optind : 1;
switch (c) {
case 0:
printf ("option %s", long_options[option_index].name);
if (optarg)
printf (" with arg %s", optarg);
printf ("\n");
break;
case '0':
case '1':
case '2':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf ("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf ("option %c\n", c);
break;
case 'a':
printf ("option a\n");
aopt = 1;
break;
case 'b':
printf ("option b\n");
bopt = 1;
break;
case 'c':
printf ("option c with value '%s'\n", optarg);
copt = optarg;
break;
case 'd':
printf ("option d with value '%s'\n", optarg);
dopt = optarg;
break;
case '?':
break;
default:
printf ("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc) {
printf ("non-option ARGV-elements: ");
while (optind < argc)
printf ("%s ", argv[optind++]);
printf ("\n");
}
exit (0);
}
#包括/*用于printf*/
#包括/*用于退出*/
#包括/*用于getopt_long;POSIX标准getopt在unistd.h中*/
int main(int argc,字符**argv){
INTC;
整数位数_optind=0;
int aopt=0,bopt=0;
char*copt=0,*dopt=0;
静态结构选项长_选项[]={
{“添加”,1,0,0},
{“追加”,0,0,0},
{“删除”,1,0,0},
{“详细”,0,0,0},
{“create”,1,0,'c'},
{“文件”,1,0,0},
{NULL,0,NULL,0}
};
int option_index=0;
而(c=getopt_long(argc,argv,abc:d:012),,
长选项和选项索引)!=-1){
int这个选项=optind?optind:1;
开关(c){
案例0:
printf(“选项%s”,长选项[选项索引].name);
如果(optarg)
printf(“带有参数%s”,optarg);
printf(“\n”);
打破
案例“0”:
案例“1”:
案例“2”:
if(digital\u optind!=0&&digital\u optind!=this\u optind)
printf(“数字出现在两个不同的argv元素中。\n”);
数字\u optind=此\u选项\u optind;
printf(“选项%c\n”,c);
打破
案例“a”:
printf(“选项a\n”);
aopt=1;
打破
案例“b”:
printf(“选项b\n”);
bopt=1;
打破
案例“c”:
printf(“值为'%s'\n的选项c”,optarg);
copt=optarg;
打破
案例“d”:
printf(“值为“%s”\n的选项d”,optarg);
dopt=optarg;
打破
案例“?”:
打破
违约:
printf(“?getopt返回的字符代码0%o???\n”,c);
}
}
如果(选项D
我不太理解选项long\u options[]
对象
第一列
我认为long\u options[]
的第一个“列”应该是用户在命令行中使用的long标志(后面是--
)
第二列
我原以为第二列应该只包含无参数
,必需参数
,或可选参数
,但我看到的是0和1
第三列
我不懂第三栏
第四列和最大标志数
第四列是在switch语句中使用的唯一标识符。然而,这让我感到困惑,好像唯一标识符只能是一个字符,那么我们是否只限于所有小写字母(26)+所有大写字母(26)+数字(10)+最终是一些特殊字符,最多有62个不同的参数。这是getopt
的限制?如果我弄错了,那么如何在getopt_long
(“abc:d:012”
)的第三个参数中指示两个以上的字符来标识标志
我假设
option long_options[]
的最后一行是用于getopt
返回-1
的时间,因此只要它存在,就不重要。结构选项数组在我摘录的[Note 1]中精确定义:
longopts
是指向在
中声明为
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
不同字段的含义如下:
name
是长选项的名称
has_arg
为:无参数
(或0),如果选项不带参数<代码>必需参数(或1),如果选项需要参数;或可选参数
(或2),如果选项采用可选参数
标志
指定如何返回长选项的结果。如果标志为NULL
,则getopt_long()
返回val
。(例如,调用程序可以将val
设置为等效的短选项字符。)否则,getopt_long()
返回0,并且flag
指向一个变量,如果找到该选项,则该变量设置为val
,如果找不到该选项,则保持不变
val
是要返回的值,或要加载到标志所指向的变量中的值
数组的最后一个元素必须用零填充
因此,您通常会对第二个元素使用符号常量(has_arg
),但手册页允许您使用0、1或2,可能是为了向后兼容。(维基百科应该使用符号常量IMHO,但这是维基百科和它的编辑器之间的事。)
getopt_long
返回一个int
,而不是char
。如果标志
(第三个)字段为空
(或等效为0),则将返回val
(第四个)字段,该字段可以是符合int
的任何内容。字符肯定适合int
,因此您可以返回等效的短选项字符(如手册中所述),但您没有义务这样做getopt
还返回一个int
,但由于它总是返回一个选项字符(或错误指示),因此有大量的int
值它永远不会返回。[注2]
如果第三个字段不是NULL
,则应指向int
类型的变量,getopt_long
将存储<
enum FROBNICATE { FROB_UNSET = -1, FROB_NO = 0, FROB_YES = 1 };
/* ... */
/* This is conceptually an enum, but `getopt_long` expects an int */
int frob_flag = FROB_UNSET;
struct option long_opts = {
/* ... */
{"frobnicate", no_argument, &frob_flag, FROB_YES},
{"unfrobnicated", no_argument, &frob_flag, FROB_NO},
/* ... */
{NULL, 0, NULL, 0}
};
/* Loop over arguments with getopt_long;
In the switch statement, you can ignore the returned value
0 because the action has been fully realized by setting the
value of a flag variable.
*/
if (frob_flag == FROB_UNSET)
frob_flag = get_default_frobnication();