- getopt() - 处理命令行参数
//函数原型
#include <unistd.h>
int getopt(int argc,char *const argv[ ],const char *optstring);
参数说明:
**前两个参数是main()函数的两个参数,第3个参数是选项字符串。
**返回值为int类型,我们知道char类型是可以转换成int类型的,每个字符都有其对应的整数值,因此这个返回值返回的其实就是一个字符,就是选项字符串里的选项字符.
当传入的argv中的选项全部被解析,getopt()返回-1,这也是getopt进行选项解析的循环截至条件;
## 介绍几个与该函数相关的全局变量
extern char *optarg; //保存选项后面的参数
extern int optind; //指示下一个要读取的选项参数在argv中的位置
extern int opterr; //表示是否将错误信息输出到标准错误stderr,为0时表示不输出,opterr非零时产生的错误要输出到stderr上
extern int optopt; //表示不在选项字符串optstring中的选项
## 选项字符串
"a:b:cd::e",这就是一个选项字符串,对应到的命令行的选项就是:-a,-b,-c,-d,-e。冒号表示参数,一个冒号就表示这个选项后面必须带有参数(没有参数会报错)。参数
可以和选项连在一起写,也可以用空格隔开,例如-a123和-a 123都表示123是-a的参数;两个冒号(::)表示这个选项的参数是可选的,既可以有参数,也可以没有参数,但
是注意有参数时,参数和选项之间不能有空格(有空格会报错),这一点和只有一个冒号的选项是有区别的。对于上面的"cd:",选项-c后面是没有参数的,选项-d后面需要有
参数。
## 一般用法
while((ret = getopt(argc, argv, "a:b:cd::e")) != -1)
{
switch(ret)
{
case 'a':
...
break;
case 'b':
...
break;
...
case '?':
...
break;
case ':'
...
break;
default:
...
}
}
<说明>
1. 当传入的argv中的选项全部被解析完成,getopt()函数返回-1,这就是getopt进行解析的循环截止条件。
2. 如果argv中解析出optstring中描述的选项字符,则返回该字符,如果该选项指定了参数,则全局指针变量optarg指向该参数;
3. 如果getopt遇到一个非optstring指定的选项字符,这表示该选项是未识别的,返回'?',并且将该选项存放到全局变量optopt中;
4. 如果optstring指定了选项必须带参数,但传入的相应option丢失了参数,返回值依赖于optstring的第一个字符,若第一个字符是':',返回':',否则返回'?';由于非法
的选项返回也是'?',所以常常optstring的第一个字符指定为':';同时将该选项存放到全局变量optopt中。例如: ":a:b:cd::e"
【拓展】getopt_long() - 支持长选项的命令解析
头文件: #include<getopt.h>
原 型: int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex);
形参说明:
optstring: 选项字符串。单个字符选项的用法和getopt()函数的一样。
longopts:
struct option{
const char *name; //表示的是长参数名
int has_arg; //has_arg有3个值,no_argument(或者是0),表示该参数后面不跟参数值;required_argument(或者是1),表示该参数后面一定要跟个参数值
//optional_argument(或者是2),表示该参数后面可以跟,也可以不跟参数值
int *flag; //用来决定,getopt_long()的返回值到底是什么。如果flag是null(通常情况),则函数会返回与该项option匹配的val值;如果flag不是NULL,则
//将val值赋予flag所指向的内存,并且返回值设置为0。
int val; //和flag联合决定返回值
};
** 举例如下:
struct option long_options[] = {
{"a123", required_argument, 0, 'a'},
{"c123", no_argument, 0, 'c'},
};
<说明> 如果命令行的参数是-a 123,那么调用getopt_long()将返回字符'a',并且将字符串123由optarg返回(注意注意!字符串123由optarg带回!optarg不需要定义,在
getopt.h中已经有定义),那么,如果命令行参数是-c,那么调用getopt_long()将返回字符'c',而此时,optarg是null。最后,当getopt_long()将命令行所有参数全部解析
完成后,返回-1。
required_argument(或者是1)时,参数输入格式为: --参数 值 或者 --参数=值。
optional_argument(或者是2)时,参数输入格式只能为: --参数=值。
longindex: 表示当前长参数在longopts中的索引值。
extern char* optarg;
extern int optind, opterr, optopt;
optarg:指向当前选项后面的参数字符串的指针。
optind:再次调用getopt_long时的下一个argv指针索引。
optopt:表示最后一个未知选项。
示例程序
#include <unistd.h>
#include <stdio.h>
int main(int argc, char * argv[])
{
int ch;
printf("\n");
printf("optind: %d, opterr: %d\n",optind,opterr);
printf("--------------------------\n");
while ((ch = getopt(argc, argv, ":ab:c:de::")) != -1){
printf("optind: %d\n", optind);
switch (ch)
{
case 'a':
printf("HAVE option: -a\n\n");
break;
case 'b':
printf("HAVE option: -b\n");
printf("The argument of -b is %s\n\n", optarg);
break;
case 'c':
printf("HAVE option: -c\n");
printf("The argument of -c is %s\n\n", optarg);
break;
case 'd':
printf("HAVE option: -d\n\n");
break;
case 'e':
printf("HAVE option: -e\n");
printf("The argument of -e is %s\n\n", optarg);
break;
case '?':
printf("Unknown option: %c\n",(char)optopt);
break;
case ':':
printf("option: %c missing argument\n",optopt);
break;
default:
printf("optopt: %c\n",ch);
}
}
return 0;
}