3、实例
说千道万,不如来一个实例:
#include<stdio.h>
#include<unistd.h>
#include<getopt.h>
int main(intargc, char *argv[])
{
int opt;
char *string = "a::b:c:d";
while ((opt = getopt(argc, argv, string))!= -1)
{
printf("opt = %c\t\t", opt);
printf("optarg = %s\t\t",optarg);
printf("optind = %d\t\t",optind);
printf("argv[optind] = %s\n",argv[optind]);
}
}
正确输入参数,执行结果如下:
peng@ubuntu:~/work/test$ ./peng -a100 -b 200 -c 300 -d
opt = a optarg = 100 optind = 2 argv[optind] = -b
opt = b optarg = 200 optind = 4 argv[optind] = -c
opt = c optarg = 300 optind = 6 argv[optind] = -d
opt = d optarg = (null) optind = 7 argv[optind] = (null)
或者
ork/test$ ./peng -a100 -b200 -c300 -d
opt = a optarg = 100 optind = 2 argv[optind] = -b200
opt = b optarg = 200 optind = 3 argv[optind] = -c300
opt = c optarg = 300 optind = 4 argv[optind] = -d
opt = d optarg = (null) optind = 5 argv[optind] = (null)
输入选项参数错误的情况
peng@ubuntu:~/work/test$ ./peng -a 100 -b 200 -c 300 -d
opt = a optarg = (null) optind = 2 argv[optind] = 100
opt = b optarg = 200 optind = 5 argv[optind] = -c
opt = c optarg = 300 optind = 7 argv[optind] = -d
opt = d optarg = (null) optind = 8 argv[optind] = (null)
导致解析错误,第一个 optarg = null,实际输入参数 100,由于格式不正确造成的(可选参数格式固定)
参数丢失,也会导致错误
peng@ubuntu:~/work/test$ ./peng -a -b 200 -c
opt = a optarg = (null) optind = 2 argv[optind] = -b
opt = b optarg = 200 optind = 4 argv[optind] = -c
./peng: option requires an argument -- 'c'
opt = ? optarg = (null) optind = 5 argv[optind] = (null)
c选项是必须有参数的
命令行选项未定义,-e选项未在optstring中定义,会报错:
peng@ubuntu:~/work/test$ ./peng -t
./peng: invalid option -- 't'
opt = ? optarg = (null) optind = 2 argv[optind] = (null)
四、getopt_long
1、定义
int getopt_long(int argc, char * const argv[], const char *optstring,
const struct option *longopts,int *longindex);
功能:
包含 getopt 功能,增加了解析长选项的功能如:--prefix --help
参数:
longopts
指明了长参数的名称和属性
longindex
如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是 longopts 的下标值
返回:
对于短选项,返回值同 getopt 函数;
对于长选项,
如果 flag 是 NULL ,返回 val ,否则返回 0 ;
对于错误情况返回值同 getopt 函数
2、struct option
struct option {
const char *name; /* 参数名称 */
int has_arg; /* 指明是否带有参数 */
int *flag; /* flag=NULL时,返回value;不为空时,*flag=val,返回0 */
int val; /* 用于指定函数找到选项的返回值或flag非空时指定*flag的值 */
};
参数has_arg 说明:has_arg 指明是否带参数值,其数值可选:
no_argument
表明长选项不带参数,如:–name, --help
required_argument
表明长选项必须带参数,如:–prefix /root或 --prefix=/root
optional_argument
表明长选项的参数是可选的,如:–help或 –prefix=/root,其它都是错误
3、实例
#include<stdio.h>
#include<unistd.h>
#include<getopt.h>
int main(intargc, char *argv[])
{
int opt;
int digit_optind = 0;
int option_index = 0;
char *string = "a::b:c:d";
static struct option long_options[] =
{
{"reqarg", required_argument,NULL, 'r'},
{"optarg", optional_argument,NULL, 'o'},
{"noarg", no_argument, NULL,'n'},
{NULL, 0, NULL, 0},
};
while((opt =getopt_long_only(argc,argv,string,long_options,&option_index))!= -1)
{
printf("opt = %c\t\t", opt);
printf("optarg = %s\t\t",optarg);
printf("optind = %d\t\t",optind);
printf("argv[optind] =%s\t\t", argv[optind]);
printf("option_index = %d\n",option_index);
}
}
正确执行命令
peng@ubuntu:~/work/test$ ./long --reqarg 100 --optarg=200 --noarg
opt = r optarg = 100 optind = 3 argv[optind] =--optarg=200 option_index = 0
opt = o optarg = 200 optind = 4 argv[optind] =--noarg option_index = 1
opt = n optarg = (null) optind = 5 argv[optind] =(null) option_index = 2
或者
peng@ubuntu:~/work/test$ ./long –reqarg=100 --optarg=200 --noarg
opt = o optarg = 200 optind = 3 argv[optind] =--noarg option_index = 1
opt = n optarg = (null) optind = 4 argv[optind] =(null) option_index = 2
可选选项可以不给参数
peng@ubuntu:~/work/test$ ./long --reqarg 100 --optarg --noarg
opt = r optarg = 100 optind = 3 argv[optind] =--optarg option_index = 0
opt = o optarg = (null) optind = 4 argv[optind] =--noarg option_index = 1
opt = n optarg = (null) optind = 5 argv[optind] =(null) option_index = 2
输入长选项错误的情况
peng@ubuntu:~/work/test$ ./long --reqarg 100 --optarg 200 --noarg
opt = r optarg = 100 optind = 3 argv[optind] =--optarg option_index = 0
opt = o optarg = (null) optind = 4 argv[optind] =200 option_index = 1
opt = n optarg = (null) optind = 6 argv[optind] =(null) option_index = 2
五、getopt_long_only
getopt_long_only 函数与 getopt_long 函数使用相同的参数表,在功能上基本一致
只是 getopt_long 只将 --name 当作长参数,但 getopt_long_only 会将 --name 和 -name 两种选项都当作长参数来匹配
getopt_long_only 如果选项 -name 不能在 longopts 中匹配,但能匹配一个短选项,它就会解析为短选项。
六、综合实例
下面这个例子,是一口君从开源项目ifplug提取出来的命令提取小例子,
大家可以根据自己需要,基于这个框架,定制自己的程序。
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <getopt.h>
#include <sys/param.h>
#define ETHCHECKD_VERSION "1.1"
int delay_up = 0;
char *interface = "eth0";
void usage(char *p) {
if (strrchr(p, '/'))
p = strchr(p, '/')+1;
printf("%s [options]\n"
" -i --iface=IFACE Specify ethernet interface (%s)\n"
" -d --delay-up=SECS Specify delay time (%i)\n"
" -h --help Show this help\n",
p,
interface,
delay_up);
}
void parse_args(int argc, char *argv[]) {
static struct option long_options[] = {
{"iface", required_argument, 0, 'i'},
{"delay-up", required_argument, 0, 'd'},
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'v'},
{0, 0, 0, 0}
};
int option_index = 0;
int help = 0, _kill = 0, _check = 0, _version = 0, _suspend = 0, _resume = 0, _info = 0;
for (;;) {
int c;
if ((c = getopt_long(argc, argv, "i:d:hv", long_options, &option_index)) < 0)
break;
switch (c) {
case 'i' :
interface = strdup(optarg);
printf("interface %s\n",interface);
break;
case 'd':
delay_up = atoi(optarg);
printf("delay_up %d\n",delay_up);
break;
case 'h':
usage(argv[0]);
break;
case 'v':
printf("peng "ETHCHECKD_VERSION"\n");
break;
default:
fprintf(stderr, "Unknown parameter.\n");
exit(1);
}
}
}
static volatile int alarmed = 0;
int main(int argc, char* argv[]) {
parse_args(argc, argv);
return 0;
}
下面是测试结果
短选项
peng@ubuntu:~/work/test$ ./param -h
param [options]
-i --iface=IFACE Specify ethernet interface (eth0)
-d --delay-up=SECS Specify delay time (0)
-h --help Show this help
peng@ubuntu:~/work/test$ ./param -v
peng 1.1
peng@ubuntu:~/work/test$ ./param -vh
peng 1.1
param [options]
-i --iface=IFACE Specify ethernet interface (eth0)
-d --delay-up=SECS Specify delay time (0)
-h --help Show this help
peng@ubuntu:~/work/test$ ./param -i eth3 -d 15
interface eth3
delay_up 15
peng@ubuntu:~/work/test$ ./param -i eth3 -d 15 -h
interface eth3
delay_up 15
param [options]
-i --iface=IFACE Specify ethernet interface (eth3)
-d --delay-up=SECS Specify delay time (15)
-h --help Show this help |