getopt是在开发中很常用的函数,用来获取命令行的参数,使用getopt可以给我们很多方便,免得我们使用大量的strcmp来判断argv。

函数的原型如下:

int getopt(int argc, char * const argv[],
const char *optstring);</p>

extern char *optarg;
extern int optind, opterr, optopt;

#include </p>

int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);

int getopt_long_only(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
</pre>
其中getopt市只能用来获取短参数,例如-h,而getopt_long可以获取短参数也可以获取长参数(例如 ---help)。getopt_long_only 则顾名思义,只能获取长参数。

 

这里我们重点介绍get_opt & get_opt_long.

先来说说返回值:如果getopt执行成功,他将会返回option character,如果没有option了,则返回-1

这是一段基本的示例代码

       #include
#include
#include </p>

int
main(int argc, char *argv[])
{
int flags, opt;
int nsecs, tfnd;

nsecs = 0;
tfnd = 0;
flags = 0;
while ((opt = getopt(argc, argv, "nt:")) != -1) {
switch (opt) {
case 'n':
flags = 1;
break;
case 't':
nsecs = atoi(optarg);
tfnd = 1;
break;
default: /* '?' */
fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
argv[0]);
exit(EXIT_FAILURE);
}
}

printf("flags=%d; tfnd=%d; optind=%d\n", flags, tfnd, optind);

if (optind >= argc) {
fprintf(stderr, "Expected argument after options\n");
exit(EXIT_FAILURE);
}

printf("name argument = %s\n", argv[optind]);

/* Other code omitted */

exit(EXIT_SUCCESS);
}
</pre>
这里重点解释下optind。 optind的值是第一个非options的argc,这里还有一点很有趣,在执行getopt时会将argc重新排序。将options放到前面,非options放到后面。 例如: command -c 会排序成为 command -c ,这时的optind就等于排序后file的argc == 3。这一点值得大家注意。</p>

上面的示例代码里用了flags,可以通过判断flags的真假来判断用户是否输入了 options 。实际应用中,有一个好用的方式来判断用户是否输入了非选项参数</p>

if (optind == argc) {
/* Code */
}</pre>
再来简单的介绍下getopt_long</p>

首先使用getopt_long 需要下面这个结构体

static struct option long_options[] = {
{"add", required_argument, 0, 0 },
{"help", no_argument, 0, 'h' },
{"file", required_argument, 0, 'f' },
{0, 0, 0, 0 }
};</pre>
这里面的required_argument意味着后面需要接参数,最后一个0意味着不与短选项相对应。让我们看下示例代码</p>
#include      /* for printf */
#include /* for exit */
#include </p>

int
main(int argc, char **argv)
{
int c;
int digit_optind = 0;

while (1) {
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] = {
{"add", required_argument, 0, 0 },
{"append", no_argument, 0, 0 },
{"delete", required_argument, 0, 0 },
{"verbose", no_argument, 0, 0 },
{"create", required_argument, 0, 'c'},
{"file", required_argument, 0, 0 },
{0, 0, 0, 0 }
};

c = getopt_long(argc, argv, "abc:d:012",
long_options, &option_index);
if (c == -1)
break;

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");
break;

case 'b':
printf("option b\n");
break;

case 'c':
printf("option c with value '%s'\n", optarg);
break;

case 'd':
printf("option d with value '%s'\n", 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(EXIT_SUCCESS);
}
</pre>
与短选项对应的好办,检测到这些长选项时会返回其对应的短选项,可是不对应的呢?

这里就要用到option_index了,比如上面的源代码中有很多不对应短选项的,那么我们如何判断呢? 方法就是

case 0:
if(opt_index == 0) /*code */
if(opt_index == 1) /*code */
break;</pre>
option long_options[]结构体里的第一项是0,这样以此类推,可以轻易地确定用户输入的long_option。</p>