https://www.cnblogs.com/hellokitty2/p/9102924.html
getopt_long()函数
1. 原型¶
getopt_long函数包含了getopt函数的功能,并且还可以指定“长参数”(或者说长选项),与getopt函数对比,getopt_long比其多了两个参数。
#define _GNU_SOURCE
#include <getopt.h>
extern char *optarg;
extern int optind, opterr, optopt;
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);
getopt_long_only与getopt_long的区别在于:getopt_long仅仅只能将"--"开始的选项视为长选项,但getopt_long_only将"-"开头选项也会视为长选项,当长选项列表均不满足时,且短选项满足时,"-"才会解析为短选项。
only可以使用 -arg 123和--arg 123,而非only只能用--arg 123,建议使用only版。
2. 描述¶
1、注意相比getopt,使用getopt_long需要加头文件
3. struct option¶
struct option {
const char *name;
int has_arg; // 0/1/2
int *flag;
int val; // 返回值,可以是0 1 2 'a' 之类的
};
name: 长选项名 has_arg: 是否带参数或可选参数,这个值在getopt.h中有宏定义,如下:
- define no_argument 0 表明这个长参数不带参数(即不带数值,如:--name)
- define required_argument 1 表明这个长参数必须带参数(即必须带数值,如:--name Bob)
- define optional_argument 2 表明这个长参数后面带的参数是可选的,(即--name和--name Bob均可)
flag: 确定函数返回值的情况,如果flag==NULL,则识别选项后 函数返回val(常用的如:设置val为长命令的短命令字符);否则,识别后getopt_long返回0,flag指向一个设置到val的变量; val: 设置为函数返回值,字符常量返回值('m', 'n', 0 , 1, 2, '2',即ascii ),可以设成数字,如果不想成为短选项,不要设成字母字符,或者是flag指向的变量;这里要注意不要写-1到val,否则其作用是getopt_long返回-1,然后停止解析选项;如果flag是NULL,那么val通常是个字符常量,用于函数的返回值,如果短选项和长选项一致,那么该字符就应该与optstring中出现的这个选项的参数相同;v
struct option long_options[]数组的最后一个元素必须是全0填充,否则会报段错误
4. 返回值¶
每次调用getopt_long,它会解析一个符号,返回相应的短选项字符,如果解析完毕返回-1 如果getopt_long遇到一个无效的选项字符,它会打印一个错误消息并且返回'?' 当getopt_long解析到一个长选项并且发现后面没有参数则返回':',表示缺乏参数。
当处理一个参数时,全局变量optarg指向下一个要处理的变量。当getopt_long处理完所有的选项后,全局变 量optind指向第一个未知的选项索引。
5. Example¶
5.1 例1¶
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>
int main(int argc, char **argv)
{
int opt; // 带回getopt_long的返回值
int option_index = 0; // 最后一个参数,获得值
// short option, if only use long otpion, use NULL.
char *optstring = "a:b:c:d";
// long option, if only use short option, use NULL.
static struct option long_options[] = { // long option
{"reqarg", required_argument, NULL, 'r'}, // long_option_index = 0
{"noarg", no_argument, NULL, 'n'}, // long_option_index = 1
{"optarg", optional_argument, NULL, 'o'}, // long_option_index = 2
{"opt1", optional_argument, NULL, '1'}, // long_option_index = 2
{"opt2", optional_argument, NULL, '2'}, // long_option_index = 2
{"opt1", optional_argument, NULL, 1}, // long_option_index = 2
{0, 0, 0, 0}
};
// while ((opt = getopt_long(argc, argv, optstring, long_options, &option_index)) != -1)
while ((opt = getopt_long_only(argc, argv, optstring, long_options, &long_option_index)) != -1)
{
printf("opt = %c\n", opt);
printf("optarg = %s\n", optarg); // 内置全局变量
printf("optind = %d\n", optind); // 内置全局变量
printf("argv[optind - 1] = %s\n", argv[optind - 1]);
printf("option_index = %d\n\n", long_option_index);
}
return 0;
}
./test_getopt -a 100 --reqarg 100 --noarg
opt = a
optarg = 100
optind = 3
argv[optind - 1] = 100
option_index = 0
opt = r
optarg = 100
optind = 5
argv[optind - 1] = 100
option_index = 0
opt = n
optarg = (null)
optind = 6
argv[optind - 1] = --noarg
option_index = 1
------------------------------------------
./a.out -a 100 -reqarg 200 --noarg -m // 没有-m参数,所以会报错
opt = a
optarg = 100
optind = 3
argv[optind - 1] = 100
option_index = 0
opt = r
optarg = 200
optind = 5
argv[optind - 1] = 200
option_index = 0
opt = n
optarg = (null)
optind = 6
argv[optind - 1] = --noarg
option_index = 1
./a.out: unrecognized option '-m'
opt = ?
optarg = (null)
optind = 7
argv[optind - 1] = -m
option_index = 1
5.2 例2¶
#include <stdio.h>
#include <getopt.h>
int do_name, do_gf_name;
char *l_opt_arg;
static const char *shortopts = "l:ng";
struct option longopts[] = {
{"name", no_argument, NULL, 'n'},
{"good", no_argument, NULL, 'g'},
{"love", required_argument, NULL, 'l'},
{0, 0, 0, 0},
};
int main (int argc, char *argv[])
{
int c;
while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
{ // c是longopts中的
switch (c)
{
case 'n':
printf ("nnnnn.\n");
break;
case 'g':
printf ("ggggg.\n");
break;
case 'l':
l_opt_arg = optarg;
printf ("%s!\n", l_opt_arg);
break;
case '?':
default:
printUsageInfo();
break;
}
}
return 0;
}