1. 家族
- 头文件:unistd.h
- 原型:int getopt(int argc,char * const argv[ ],const char * optstring)
- 小弟1:extern char* optarg; 保存选项的参数;
- 小弟2:extern int optind; 保存下一个检索位置;
- 小弟3:extern int opterr; 保存错误信息;
- 小弟4:extern int optopt;
2. 选项/选项字符串
- 选项
"gcc helloworld.c -o helloworld.out" 中-o就是选项, helloworld.out就是参数。特殊的是,当某些选项不带参数时可以一起使用,如rm -rf,tar -vjzf等等。
- 选项字符串
"a:b:cd::e",这就是一个选项字符串。对应到命令行就是-a ,-b ,-c ,-d, -e 。
冒号表示参数,一个冒号就表示这个选项后面必须带有参数(没有带参数会报错哦),但是这个参数可以和选项连在一起写,也可以用空格隔开,比如-a123 和-a 123(中间有空格) 都表示123是-a的参数;
两个冒号的就表示这个选项的参数是可选的,但要注意有参数时,参数与选项之间不能有空格(有空格会报错的哦),这一点和一个冒号时是有区别的。
3. 实战
int main(int argc, char * argv[])
{
int i;
printf("--------------------------\n");
for(i=0;i<argc;i++)
{
printf("%s\n",argv[i]);
}
printf("--------------------------\n");
int ch;
printf("optind:%d,opterr:%d\n",optind,opterr);
printf("--------------------------\n");
printf("----------------------------\n");
while ((ch = getopt(argc, argv, "ab:c:de::")) != -1)
{
switch (ch)
{
case 'a':
printf("HAVE option: -a\n");
break;
case 'b':
printf("HAVE option: -b\n");
printf("The argument of -b is %s\n", optarg);
break;
case 'c':
printf("HAVE option: -c\n");
printf("The argument of -c is %s\n", optarg);
break;
case 'd':
printf("HAVE option: -d\n");
break;
case 'e':
printf("HAVE option: -e\n");
printf("The argument of -e is %s\n", optarg);
break;
case '?':
printf("Unknown option: %c\n",(char)optopt);
break;
}
printf("optind=%d,argv[%d]=%s\n\n",optind,optind,argv[optind]);
}
printf("--------------------------\n");
for(i=0;i<argc;i++)
{
printf("%s\n",argv[i]);
}
printf("--------------------------\n");
}
输入: ./getopt -ab x -c y -de z
输出:
--------------------------
./getopt
-ab
x
-c
y
-de
z
--------------------------
optind:1,opterr:1 //可见初始值为1
--------------------------
----------------------------
HAVE option: -a
optind=1,argv[1]=-ab //ab粘合导致下次还是1
HAVE option: -b
The argument of -b is x
optind=3,argv[3]=-c
HAVE option: -c
The argument of -c is y
optind=5,argv[5]=-de
HAVE option: -d
optind=5,argv[5]=-de
HAVE option: -e
The argument of -e is (null)
optind=6,argv[6]=z
--------------------------
./getopt
-ab
x
-c
y
-de
z
--------------------------
输入:./getopt -zheng
输出:
--------------------------
./getopt
-zheng
--------------------------
optind:1,opterr:1
--------------------------
----------------------------
./getopt: invalid option -- 'z'
Unknown option: z // case '?'的内容
optind=1,argv[1]=-zheng
./getopt: invalid option -- 'h'
Unknown option: h
optind=1,argv[1]=-zheng
HAVE option: -e //查到正确的为止
The argument of -e is ng
optind=2,argv[2]=(null)
--------------------------
./getopt
-zheng
--------------------------
输入:./getopt para1 -b x -c y para2
输出:
--------------------------
./getopt
para1
-b
x
-c
y
para2
--------------------------
optind:1,opterr:1
--------------------------
----------------------------
HAVE option: -b
The argument of -b is x
optind=4,argv[4]=-c
HAVE option: -c
The argument of -c is y
optind=6,argv[6]=para2
--------------------------
./getopt
-b //将选项及其参数移到了前面
x
-c
y
para1
para2
--------------------------