详解getopt()函数

     结合一个小例子来说明关于getopt()函数的一些概念,一定要注意区分和理解我下面说的名词,千万不能混淆了。否则就容易概念不清了。

#include <unistd.h>
#include <stdio.h>
int main(int argc, char * argv[])
{
    
	int i;
    	int ch;
    	printf("--------------------------\n");
    	for(i=0;i<argc;i++)
    	{
        	printf("%s\n",argv[i]);
    	}
    	printf("--------------------------\n");
   
    	printf("\n\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");
                     		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;
         	}
         	
         	printf("-----\n");
              	printf("optarg:%s\n",optarg); 
              	printf("optopt:%c\n",optopt);   
                printf("----------------------------\n");
       	}
    
       	printf("----------------------------\n");
      	printf("optind=%d,argv[%d]=%s\n",optind,optind,argv[optind]);

    	printf("--------------------------\n");
    	for(i=0;i<argc;i++)
    	{
        	printf("%s\n",argv[i]);
    	}
    	printf("--------------------------\n");

    	return 0;
}
如果执行命令:./main zheng -b "qing er" han -c123 qing
命名包含了选项-b,其参数"qing er";-c,其参数123,程序参数(操作数)zheng,han,qing 和程序名./main

则:
./main zheng -b     "qing er"         han        -c123         qing
argv[0] argv[1] argv[2] argv[3] argv[4] argv[5] argv[6]

argc = 7

main()函数参数:包含程序名,选项,选项参数,程序参数(操作数)
main()函数参数个数argc:包含程序名,选项,选项参数,程序参数(操作数) ,是他们的字符串数之总和。
main()函数参数字符串数组argv[]:包含程序名字符串,选项字符串,选项参数字符串,程序参数(操作数)字符串

选项字符串:"a:b:cd::e",由getopt(argc, argv, "ab:c:de::")函数的第三个参数指定。

选项:分带参和不带参选项 ,执行命令时,选项可有可无,如-b,-c等等。选项后的冒号表示参数,一个冒号就表示这个选项后面必须带有参数,不带参数报错。

getopt() 所设置的全局变量包括:

char *optarg——当前选项参数字串(如果有的话)。不是选项的字串,如上命令的话,它的值先是"qing er",后是123。
int optind——argv的当前索引值(下一个argv)。当getopt()在while循环中使用时,循环结束后,剩下的字串视为操作数,在 argv[optind]至argv[argc-1]中可以找到剩下的那些操作数。
int opterr——opterr非零表示产生的错误要输出到stderr上,初值为1。
int optopt——当发现无效选项字符之时,getopt()函数或返回'?'字符,或返回':'字符,并且optopt包含了所发现的无效选项字符。它还是一个选项,是不在选项字串"a:b:cd::e"中的选项,但不是程序参数(操作数),不是选项参数。


optind:实际上真正的参数是用第二个main()函数的参数开始,也就是argv[1],所以optind的初始值为1;

选项和参数写在一起,他们占用一个main()函数参数字符串argv[n],如上面选项-c,其参数123,写在一起-c123:所以他两占一起占用argv[5]。

        最后要说明一下,getopt()会改变argv[]中参数的顺序。经过多次getopt()后,argv[]中的选项和选项的参数会被放置在数组前面,而optind 会指向第一个非选项和参数的位置。
执行getope之前:argv[]的输出:
./main
zheng
-b
qing er
han
-c123
qing


执行getopt后,argv[]的输出:
./main
-b
qing er
-c123
zheng
han
qing

此时optind指向第一个非选项非参数(操作数或叫程序参数)zheng

        前面提到过不带参数的选项可以写在一起,所以当getopt()找到-z的时候,发现在optstring 中没有,这时候他就认为h也是一个选项,也就是-h和-z写在一起了,依次类推,直到找到-e,发现optstring中有。
如果这样执行:
./main -zheng -b "qing er" han -c123 qing

则能识别-zheng中的-e选项,但一样不能把han中的a识别为-a选项。


  • 8
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值