gpt4 book ai didi

c - 使用 `option long_options[]` 时了解 `getopt_long`

转载 作者:行者123 更新时间:2023-12-04 21:25:16 25 4
gpt4 key购买 nike

我正在尝试学习使用 getopt_long 。从 wikipedia ,我看到了代码

#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);
}

我不太明白 option long_options[] 对象。

第一列

我认为 long_options[] 的第一个“列”应该是用户在命令行中使用的长标志( -- 后面的任何内容)。

第二列

我原以为第二列应该只包含 no_argumentrequired_arguemntoptional_argument ,但我看到的是 0 和 1。

第三列

我不明白第三列。

第四列和最大标志数

第四列是在 switch 语句中使用的唯一标识符。然而,这让我感到困惑,好像唯一标识符只能是一个字符,那么我们是否仅限于所有小写字母 (26) + 所有大写字母 (26) + 数字 (10) + 最后一些特殊字符总共最多 62 个不同的参数。这是 getopt 的限制吗?如果我弄错了,那么如何在 getopt_long ( ""abc:d:012"" ) 的第三个参数中指示两个以上的字符来标识标志

我想 option long_options[] 的最后一行是在 getopt 返回 -1 时使用的,因此只要它存在就无关紧要。

最佳答案

struct option 数组在 man getopt_long [Note 1] 中精确定义,我摘录:

longopts is a pointer to the first element of an array of struct option declared in <getopt.h> as

   struct option {
const char *name;
int has_arg;
int *flag;
int val;
};

The meanings of the different fields are:

name is the name of the long option.

has_arg is: no_argument (or 0) if the option does not take an argument; required_argument (or 1) if the option requires an argument; or optional_argument (or 2) if the option takes an optional argument.

flag specifies how results are returned for a long option. If flag is NULL, then getopt_long() returns val. (For example, the calling program may set val to the equivalent short option character.) Otherwise, getopt_long() returns 0, and flag points to a variable which is set to val if the option is found, but left unchanged if the option is not found.

val is the value to return, or to load into the variable pointed to by flag.

The last element of the array has to be filled with zeros.



因此,您通常会为第二个元素 ( has_arg ) 使用符号常量,但联机帮助页允许您使用 0、1 或 2,大概是为了向后兼容。 (维基百科应该使用符号常量,恕我直言,但那是维基百科和它的编辑之间的。)
getopt_long 返回 int ,而不是 char 。如果 flag(第三个)字段是 NULL(或等效的 0),那么 val(第四个)字段将被返回,它可以是任何适合 int 的字段。字符肯定适合 int ,因此您可以返回等效的短选项字符(如联机帮助页中所述),但您没有义务这样做。 getopt 也返回一个 int ,但由于它总是返回一个选项字符(或一个错误指示),有大量的 int 值永远不会返回。 [笔记2]

如果第三个字段不是 NULL ,则应指向 int 类型的变量, getopt_long 将在其中存储 val 值。例如,这可以用于 bool 标志:
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();

如联机帮助页所示,数组中的最后一个条目必须全为零(或指针成员的 NULL)。这是必要的,以便 getopt_long 知道数组在哪里结束。

笔记
  • 您的系统上可能安装了联机帮助页,在这种情况下,您只需键入 man getopt_long 即可查看 getopt_long 的文档。这应该适用于任何标准 C 库函数、任何 Gnu libc 函数,以及一般而言,您安装了 -doc 包的任何 C 库函数。 (强烈推荐。)总的来说,在查看维基百科之前,您应该先尝试联机帮助页,因为联机帮助页将是您系统上实际安装的库函数版本的文档。
  • 函数返回给定数据类型的事实并不意味着它可能返回该数据类型的任何可能值。
  • 关于c - 使用 `option long_options[]` 时了解 `getopt_long`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39966025/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com