zoukankan      html  css  js  c++  java
  • getopt()用法详解

    getopt被用来解析命令行选项参数。就不用自己写东东处理argv了。

    #include <unistd.h>
           extern char *optarg;  //选项的参数指针
           extern int optind,   //下一次调用getopt的时,从optind存储的位置处重新开始检查选项。 
           extern int opterr,  //当opterr=0时,getopt不向stderr输出错误信息。
           extern int optopt;  //当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,该选项存储在optopt中,getopt返回'?’、
           int getopt(int argc, char * const argv[], const char *optstring);


     调用一次,返回一个选项。 在命令行选项参数再也检查不到optstring中包含的选项时,返回-1,同时optind储存第一个不包含选项的命令行参数。

    首先说一下什么是选项,什么是参数。

    字符串optstring可以下列元素,
    1.单个字符,表示选项,
    2.单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。
    3 单个字符后跟两个冒号,表示该选项后必须跟一个参数。参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。(这个特性是GNU的扩张)。

    getopt处理以'-’开头的命令行参数,如optstring="ab:c::d::",命令行为getopt.exe -a -b host -ckeke -d haha
    在这个命令行参数中,-a和-h就是选项元素,去掉'-',a,b,c就是选项。host是b的参数,keke是c的参数。但haha并不是d的参数,因为它们中间有空格隔开。

    还要注意的是默认情况下getopt会重新排列命令行参数的顺序,所以到最后所有不包含选项的命令行参数都排到最后。
    如getopt.exe -a ima -b host -ckeke -d haha, 都最后命令行参数的顺序是: -a -b host -ckeke -d ima haha
    如果optstring中的字符串以'+'加号开头或者环境变量POSIXLY_CORRE被设置。那么一遇到不包含选项的命令行参数,getopt就会停止,返回-1。

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main(int argc, char **argv)
    {
        int result;
    
        opterr = 0;  //使getopt不行stderr输出错误信息
    
        while( (result = getopt(argc, argv, "ab:c::")) != -1 )
        {
               switch(result)
              {
                   case 'a':
                       printf("option=a, optopt=%c, optarg=%s\n", optopt, optarg);
                       break;
                  case 'b':
                       printf("option=b, optopt=%c, optarg=%s\n", optopt, optarg);
                       break;
                  case 'c':
                       printf("option=c, optopt=%c, optarg=%s\n", optopt, optarg);
                       break;
                  case '?':
                        printf("result=?, optopt=%c, optarg=%s\n", optopt, optarg);
                        break;
                  default:
                       printf("default, result=%c\n",result);
                       break;
               }
            printf("argv[%d]=%s\n", optind, argv[optind]);
        }
        printf("result=-1, optind=%d\n", optind);   //看看最后optind的位置
    
        for(result = optind; result < argc; result++)
             printf("-----argv[%d]=%s\n", result, argv[result]);
    
     //看看最后的命令行参数,看顺序是否改变了哈。
        for(result = 1; result < argc; result++)
              printf("\nat the end-----argv[%d]=%s\n", result, argv[result]);
        return 0;
    }



    unistd里有个 optind 变量,每次getopt后,这个索引指向argv里当前分析的字符串的下一个索引,因此
    argv[optind]就能得到下个字符串,通过判断是否以 '-'开头就可。下面是个测试程序

    #include <stdio.h>
    #include <unistd.h>
    int main(int argc, char* argv[])
    {
        int tmp = 4;
       
        while( (tmp = getopt(argc, argv, "abck")) != -1  )
        {
               
               printf("-%c\t", tmp);
               int opt = optind ;
               while( opt < argc )
               {
                      if ( argv[opt][0] != '-' )
                      {
                           printf("%s\t", argv[opt]);
                           opt ++;
                      }
                      else
                          break;
               }
               printf("\n");
        }
        getchar();
    }

    说明  getopt()用来分析命令行参数。参数argc和argv是由main()传递的参数个数和内容。参数optstring 则代表欲处理的选项字符串。此函数会返回在argv 中下一个的选项字母,此字母会对应参数optstring 中的字母。如果选项字符串里的字母后接着冒号“:”,则表示还有相关的参数,全域变量optarg 即会指向此额外参数。如果getopt()找不到符合的参数则会印出错信息,并将全域变量optopt设为“?”字符,如果不希望getopt()印出错信息,则只要将全域变量opterr设为0即可。

    返回值  如果找到符合的参数则返回此参数字母,如果参数不包含在参数optstring 的选项字母则返回“?”字符,分析结束则返回-1。

    范例 
    #include<stdio.h>
    #include<unistd.h>
    int main(int argc,char **argv)
    {
    int ch;
    opterr = 0;
    while((ch = getopt(argc,argv,”a:bcde”))!= -1)
    switch(ch)
    {
    case ‘a’:
    printf(“option a:’%s’\n”,optarg);
    break;
    case ‘b’:
    printf(“option b :b\n”);
    break;
    default:
    printf(“other option :%c\n”,ch);
    }
    printf(“optopt +%c\n”,optopt);
    }



    执行  $./getopt –b
    option b:b
    $./getopt –c
    other option:c
    $./getopt –a
    other option :?
    $./getopt –a12345
    option a:’12345’

    getopt 函数

    函数定义:

    #include
    int getopt(int argc, char * const argv[],
            const char *optstring);
    
    extern char *optarg;
    extern int optind, opterr, optopt;
    
    
    #define _GNU_SOURCE
    #include
    
    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);



    getopt()函数是用来解析命令行参数的。这里,主要解释getopt_long()。

        getopt_long()的头两参数,argc和argv分别是传递给main()的参数的个数和参数数组(和main()的argc和argv是一个概念)。

        getopt_long()中,optstring是一个字符串,表示可以接受的参数。例如,"a:b:cd",表示可以接受的参数是a,b,c,d,其中,a和b参数后面

    跟有更多的参数值。(例如:-a host --b name)

        getopt_long()中,参数longopts,其实是一个结构的实例:

    struct option {
      const char *name;
        //name表示的是长参数名
      int has_arg;
        //has_arg有3个值,no_argument(或者是0),表示该参数后面不跟参数值
        //   required_argument(或者是1),表示该参数后面一定要跟个参数值
        //   optional_argument(或者是2),表示该参数后面可以跟,也可以不跟参数值
      int *flag;
        //用来决定,getopt_long()的返回值到底是什么。如果flag是null,则函数会返回与该项option匹配的val值
      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。

    看来,我说的有点混乱,那么,看个例子,我相信,代码最能说明问题:

    #include
    #include

    #include #include #include #include

    int main( int argc, char **argv ) {

     struct option long_options[] = {    {"a123",       required_argument,      0, 'a'},    {"c123",       no_argument,            0, 'c'},  }  int opt;    printf("starting... ");    while((opt = getopt_long(argc, argv, "a:c", long_options, NULL)) != -1)  {   switch (opt)   {   case 'a':     printf("It's a! ");     printf("string of a:%s ",optarg);   break;        case 'c':     printf("It's c! ");   break;        default:     printf("You should look for help! ");     exit(1);   break;               }  }  printf("end... ");  return 0; }

    #include
    #include
    
    int main( int argc, char **argv )
    {
    
     struct option long_options[] = {
       {"a123",       required_argument,      0, 'a'},
       {"c123",       no_argument,            0, 'c'},
     }
     int opt;
     
     printf("starting... ");
     
     while((opt = getopt_long(argc, argv, "a:c", long_options, NULL)) != -1)
     {
      switch (opt)
      {
      case 'a':
        printf("It's a! ");
        printf("string of a:%s ",optarg);
      break;
        
      case 'c':
        printf("It's c! ");
      break;
        
      default:
        printf("You should look for help! ");
        exit(1);
      break;            
      }
     }
     printf("end... ");
     return 0;
    }


    编译后,假设生成a.out,可以试验一下。
    ./a.out -a hello -c
    输出:
    starting...
    It's a!
    string of a:hello
    It's c!
    end...


  • 相关阅读:
    poj 2584 T-Shirt Gumbo (二分匹配)
    hdu 1757 A Simple Math Problem (乘法矩阵)
    矩阵之矩阵乘法(转载)
    poj 2239 Selecting Courses (二分匹配)
    hdu 3661 Assignments (贪心)
    hdu 1348 Wall (凸包)
    poj 2060 Taxi Cab Scheme (二分匹配)
    hdu 2202 最大三角形 (凸包)
    hdu 1577 WisKey的眼神 (数学几何)
    poj 1719 Shooting Contest (二分匹配)
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/3076699.html
Copyright © 2011-2022 走看看