- getopt()是一个C语言的函数,它用于解析命令行选项参数。
- 使用getopt()函数要引用头文件unistd.h(也可以引用getopt.h),它的函数原型是:
int getopt (int argc, char * const argv [ ], const char * optstring);
- 其中,argc和argv通常直接从main()的参数传递而来,表示参数的个数和字符串数组。optstring是一个包含正确的选项字符串,用于指定哪些选项需要参数,哪些不需要。
- 返回值为int类型,其实解析成功一个选项时,这个返回的就是一个字符,因为字符可以转为整数。
若解析完毕,则返回-1或者EOF。- 与getopt相关的重要的全局变量
- extern char* optarg;用来保存当前选项的参数;
extern int optind;在getopt()处理中,optind会告诉你当前处理所有选项的下一个位置;当getopt()处理完所有选项之后,optind将会告诉你非选项参数在argv的起始位置,使用optind++指向下一个非选项参数位置;解析完毕后返回-1;
extern int opterr;是否将错误信息输出到stderr,设置为0时表示不输出,默认为1;
extern int optopt;保存不在optstring中或在但无参数的选项.
参数optstring:是一个包含合法选项字符的字符串。
对optstring中的选项字符的处理:
(1)选项字符后面跟一个冒号“:",则此选项后要带一个参数,可以通过全局变量 optarg来获取 。
(2)选项字符后面跟两个冒号“::“,则此选项的参数是可选的,即如果提供选项参数,则选项参数必须紧跟在选项字符后面,不能以空格隔开,如”o::",则命令行中应该是这样的"-oarg",同样用optarg获取,如果没有提供值,则optarg为0
(3)如果optstring包含“W;",即W后面一个分号,那么当命令行中出现“-W foo”,它们就会被当成是一个长选项,即“–foo”。
(4)如果optstring的第一个字符是冒号’:’,那么getopt() 不会打印错误信息,返回双引号’:’。默认情况下, getopt()会在标准错误中打印错误信息。
(5)如果输入的选项字符不在合法选项字符optstring中,getopt()函数返回“?”,并将错误的字符放在optopt全局变量中。
那什么是选项字符串?就比如
gcc -o test test.c gcc -v
上面的-o、-v就是选项,其中-o是带参数的选项,其参数为test,而-v是不带参数的选项。
选项字符串其实就是具有一定格式的字符串,它决定了传给程序的参数argv中可以有哪些选项,而这些选项中哪些可以有参数。
getopt()对参数处理的三种情况:
(1)默认情况下,getopt()会在扫描时重新排列argv的内容。最终,所有非选项参数都会排在最后面。
(2)如果optstring的第一个字符是 '+'或者设置了环境变量POSIXLY_CORRECT,那么一旦遇到非选项参数,就会停止处理选项(即不会重新排列)。
(3)如optstring 第一个字符是 ‘-’,那么每一个非选项参数都将被处理,好似它们就是选项的参数。(也不会重新排列)
举例:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main(int argc,char *argv[])
{
int opt;
while((opt=getopt(argc,argv,":ab:c:d::"))!=-1)
{
switch(opt)
{
case 'a':
printf("Option %c\n",opt);
break;
case 'b':
case 'c':
printf("Option %c with value %s\n",opt,optarg);
break;
case 'd':
if(optarg!=0)
{
printf("Option %c ",opt);
printf(" value %s\n",optarg);
}
else
printf("Option without value %c \n",opt);
break;
case '?':
printf("Unknown option %c with value %s \n",optopt,argv[optind]);
break;
case ':':
printf("-%c needs value \n",optopt);
break;
}
}
for(;optind<argc;optind++)
{
printf("optind :%d and Argument: %s\n ",optind,argv[optind]);
}
for(int num=0; num<argc;num++)
printf("argv[%d]: %s\n",num,argv[num]);
return 0;
}
编译输出:
./getopt_2 -a 1 -b 2 -c 3 -d4 -e 5 Option a Option b Option c with value 3 Option d value 4 Option e optind :7 and Argument: 1 optind :8 and Argument: 2 optind :9 and Argument: 5 argv[0]: ./getopt_2 argv[1]: -a argv[2]: -b argv[3]: -c argv[4]: 3 argv[5]: -d4 argv[6]: -e argv[7]: 1 argv[8]: 2 argv[9]: 5