一、getop函数
函数头文件
#include <unistd.h>
函数原型
#include <unistd.h>
int getopt(int argc, char * const argv[], const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
函数的参数:
参数argc和argv:通常是从main的参数直接传递而来,argc是参数的数量,argv是一个常量字符串数组的地址。
参数optstring:一个包含正确选项字符的字符串,如果一个字符后面有冒号,那么这个选项在传递参数时就需要跟着一个参数。
while( (ch=getopt_long(argc, argv, "p:h")) != -1 )
例如上面这行代码,p后面有“:”所以命令行-p后要接参数,-h后面不需要接参数。
外部变量:
char *optarg:如果有参数,则包含当前选项参数字符串
int optind:argv的当前索引值。当getopt函数在while循环中使用时,剩下的字符串为操作数,下标从optind到argc-1。
int opterr:这个变量非零时,getopt()函数为“无效选项”和“缺少参数选项,并输出其错误信息。
int optopt:当发现无效选项字符之时,getopt()函数或返回 \’ ? \’ 字符,或返回字符 \’ : \’ ,并且optopt包含了所发现的无效选项字符
函数使用:
getopt函数的例子
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int ch;
while((ch = getopt(argc,argv,"a:bc::"))!= -1)
{
switch(ch)
{
case 'a':
printf("ch a:%c\n", ch);
printf("optarg a:%s\n", optarg);
printf("optind a:%d\n", optind);
printf("opterr a:%d\n", opterr);
printf("optopt a:%d\n", optopt);
printf("\n");
break;
case 'b':
printf("ch b:%c\n", ch);
printf("optarg b:%s\n", optarg);
printf("optind b:%d\n", optind);
printf("opterr b:%d\n", opterr);
printf("optopt b:%d\n", optopt);
printf("\n");
break;
case 'c':
printf("ch c:%c\n", ch);
printf("optarg c:%s\n", optarg);
printf("optind c:%d\n", optind);
printf("opterr c:%d\n", opterr);
printf("optopt c:%d\n", optopt);
printf("\n");
break;
default:
printf("ch default:%c\n", ch);
printf("optarg default:%s\n", optarg);
printf("optind default:%d\n", optind);
printf("opterr default:%d\n", opterr);
printf("optopt default:%d\n", optopt);
printf("\n");
}
}
return 0;
}
运行结果:
xiaopeng@ubuntu-14:~$ ./a.out -a
./a.out: option requires an argument -- 'a'
ch default:?
optarg default:(null)
optind default:2
opterr default:1
optopt default:97 //a的ASCII值
a的参数未输入,报错:option requires an argument – ‘a’,函数返回?,函数参数是null,optind—再次调用 getopt() 时的下一个 argv 指针的索引是2,opterr是1,打印错误信息,若设置opterr为0 ,则不打印错误信息,最后一个未知选项optopt是a。
运行结果:
xiaopeng@ubuntu-14:~$ ./a.out -a hello
ch a:a
optarg a:hello
optind a:3
opterr a:1
optopt a:0
正确输入a的参数,函数返回a,函数参数是hello,optind—再次调用 getopt() 时的下一个 argv 指针的索引是3,最后一个未知选项optopt没有,是0。
运行结果:
xiaopeng@ubuntu-14:~$ ./a.out -b hello
ch b:b
optarg b:(null)
optind b:2
opterr b:1
optopt b:0
xiaopeng@ubuntu-14:~$ ./a.out -b
ch b:b
optarg b:(null)
optind b:2
opterr b:1
optopt b:0
b选项是没有参数的,输入参数也会被忽略掉。
运行结果:
xiaopeng@ubuntu-14:~$ ./a.out -c
ch c:c
optarg c:(null)
optind c:2
opterr c:1
optopt c:0
xiaopeng@ubuntu-14:~$ ./a.out -c 1
ch c:c
optarg c:(null)
optind c:2
opterr c:1
optopt c:0
xiaopeng@ubuntu-14:~$ ./a.out -c1
ch c:c
optarg c:1
optind c:2
opterr c:1
optopt c:0
c选项的参数可以有,也可以没有,如果跟一个参数,参数必须紧跟在选项后不能以空格隔开。
运行结果:
xiaopeng@ubuntu-14:~$ ./a.out -d
./a.out: invalid option -- 'd'
ch default:?
optarg default:(null)
optind default:2
opterr default:1
optopt default:100 //d的ASCII值
并没有选项d,输入d后,报错:invalid option – ‘d’,函数返回?,最后一个未知的选项是d
运行结果:
xiaopeng@ubuntu-14:~$ ./a.out -a hello -b -c1 -d
ch a:a
optarg a:hello
optind a:3
opterr a:1
optopt a:0
ch b:b
optarg b:(null)
optind b:4
opterr b:1
optopt b:0
ch c:c
optarg c:1
optind c:5
opterr c:1
optopt c:0
./a.out: invalid option -- 'd'
ch default:?
optarg default:(null)
optind default:6
opterr default:1
optopt default:100 //d的ASCII值
二、getopt_long函数
函数头文件
#include <getopt.h>
函数原型
#include <getopt.h>
int getopt_long(int argc, char * const argv[],const char *optstring,const struct option *longopts, int *longindex);
函数的参数:
前面三个参数跟getopt函数一样(解析到短参数时返回值跟getopt一样),而长参数的解析则与longopts参数相关,该参数使用如下的结构。
struct option {
//长参数名
const char *name;
/*
表示参数的个数
no_argument(或者0),表示该选项后面不跟参数值
required_argument(或者1),表示该选项后面一定跟一个参数
optional_argument(或者2),表示该选项后面的参数可选
*/
int has_arg;
//如果flag为NULL,则函数会返回下面val参数的值,否则返回0,并将val值赋予赋予flag所指向的内存
int *flag;
//配合flag来决定返回值
int val;
};
参数longindex,表示当前长参数在longopts中的索引值,如果不需要可以置为NULL。
代码示例:
#include <stdio.h>
#include <string.h>
#include <getopt.h>
int learn=0;
static const struct option long_option[]={
{"name",required_argument,NULL,'n'},
{"learn",no_argument,&learn,1},
{NULL,0,NULL,0}
};
int main(int argc,char *argv[])
{
int opt=0;
while((opt=getopt_long(argc,argv,"n:l",long_option,NULL))!=-1)
{
switch(opt)
{
case 0:break;
case 'n':printf("name:%s ",optarg);
}
}
if(learn)
printf("learning\n");
}