getopt和getopt_long函数使用详解

**getopt和getopt_long函数使用详解**
在我们操作命令行的时候,main函数中输入参数一个一个分析不免麻烦,我们可以使用linux的参数分析函数解决此问题方便省力。
#include <unistd.h>

       int getopt(int argc, char * const argv[],
                  const char *optstring);

       extern char *optarg;
       extern int optind, opterr, optopt;

       #include <getopt.h>

       int getopt_long(int argc, char * const argv[],
                  const char *optstring,
                  const struct option *longopts, int *longindex);

       int getopt_long_only(int argc, char * const argv[],
                  const char *optstring,
                  const struct option *longopts, int *longindex);

optstring的格式举例说明比较方便,例如:

char *optstring = "abcd:";

上面这个optstring在传入之后,getopt函数将依次检查命令行是否指定了 -a, -b, -c及 -d(这需要多次调用getopt函数,直到其返回-1),当检查到上面某一个参数被指定时,函数会返回被指定的参数名称(即该字母)

最后一个参数d后面带有冒号,: 表示参数d是可以指定值的,如 -d 100 或 -d user。

optind表示的是下一个将被处理到的参数在argv中的下标值。

如果指定opterr = 0的话,在getopt、getopt_long、getopt_long_only遇到错误将不会输出错误信息到标准输出流。

其中四个变量会经常使用到:
optarg: 当前位置的参数,:后面的参数。
optind: optind表示的是下一个将被处理到的参数在argv中的下标值
opterr: 错误信息
optopt: 。

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    int opt;
    char *optstring = "a:b:c:d";

    while ((opt = getopt(argc, argv, optstring)) != -1)
    {
        printf("opt = %c\n", opt);
        printf("optarg = %s\n", optarg);
        printf("optind = %d\n", optind);
        printf("argv[optind - 1] = %s\n\n",  argv[optind - 1]);
    }

    return 0;
}

输出结果:

ubuntu:~/Desktop/getopt$ ./test_getopt -a 100 -b 200 -c admin -d
opt = a
optarg = 100
optind = 3
argv[optind - 1] = 100

opt = b
optarg = 200
optind = 5
argv[optind - 1] = 200

opt = c
optarg = admin
optind = 7
argv[optind - 1] = admin

opt = d
optarg = (null)
optind = 8
argv[optind - 1] = -d

下面来讲getopt_long函数,getopt_long函数包含了getopt函数的功能,并且还可以指定“长参数”(或者说长选项),与getopt函数对比,getopt_long比其多了两个参数:

   int getopt(int argc, char * const argv[],
               const char *optstring);

   int getopt_long(int argc, char * const argv[],
               const char *optstring,
              const struct option *longopts, int *longindex);

在这里,longopts指向的是一个由option结构体组成的数组,那个数组的每个元素,指明了一个“长参数”(即形如–name的参数)名称和性质:

       struct option {
            const char *name;
            int         has_arg;
            int        *flag;
            int         val;
        };

    name  是参数的名称

   has_arg 指明是否带参数值,其数值可选:
          no_argument (即 0) 表明这个长参数不带参数(即不带数值,如:--name)
          required_argument (即 1) 表明这个长参数必须带参数(即必须带数值,如:--name Bob)
        optional_argument(即2)表明这个长参数后面带的参数是可选的,(即--name和--name Bob均可)

   flag   当这个指针为空的时候,函数直接将val的数值从getopt_long的返回值返回出去,当它非空时,val的值会被赋到flag指向的整型数中,而函数返回值为0

    val    用于指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值。

另一个参数longindex,如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值

static const struct option long_options[]=
{
 {"force",no_argument,&force,1},
 {"reload",no_argument,&force_reload,1},
 {"time",required_argument,NULL,'t'},
 {"help",no_argument,NULL,'?'},
 {"http09",no_argument,NULL,'9'},
 {"http10",no_argument,NULL,'1'},
 {"http11",no_argument,NULL,'2'},
 {"get",no_argument,&method,METHOD_GET},
 {"head",no_argument,&method,METHOD_HEAD},
 {"options",no_argument,&method,METHOD_OPTIONS},
 {"trace",no_argument,&method,METHOD_TRACE},
 {"version",no_argument,NULL,'V'},
 {"proxy",required_argument,NULL,'p'},
 {"clients",required_argument,NULL,'c'},
 {NULL,0,NULL,0}
};
while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF )
 {
  switch(opt)
  {
   case  0 : break;
   case 'f': force=1;break;
   case 'r': force_reload=1;break; 
   case '9': http10=0;break;
   case '1': http10=1;break;
   case '2': http10=2;break;
   case 'V': printf(PROGRAM_VERSION"\n");exit(0);
   case 't': benchtime=atoi(optarg);break;       
   case 'p': 
         /* proxy server parsing server:port */
         tmp=strrchr(optarg,':');
         proxyhost=optarg;
         if(tmp==NULL)
         {
             break;
         }
         if(tmp==optarg)
         {
             fprintf(stderr,"Error in option --proxy %s: Missing hostname.\n",optarg);
             return 2;
         }
         if(tmp==optarg+strlen(optarg)-1)
         {
             fprintf(stderr,"Error in option --proxy %s Port number is missing.\n",optarg);
             return 2;
         }
         *tmp='\0';
         proxyport=atoi(tmp+1);break;
   case ':':
   case 'h':
   case '?': usage();return 2;break;
   case 'c': clients=atoi(optarg);break;
  }

从中可以学习着怎么使用getopt_long函数的使用。

你可能感兴趣的:(linux,函数,命令行)