• 【Linux开发】常用命令行解析函数getopt/getopt_long


    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/

    1.getopt
    #include <unistd.h>
    extern char *optarg;
    extern int optind;
    extern int optopt;
    extern int opterr;
    extern int optreset;
    int getopt(int argc, char * const *argv, const char *optstring);
    getopt()每调用一次返回一个选项。  argc 和 argv 很显然就是 main 函数的两个参数。
    字符串 optstring 可以包含下列元素:单个字符,字符后面接一个冒号说明后面跟随一个选项参数,字符后面接两个冒号说明后面跟随一个可有可无的选项参数。例如,一个选项字符 "x" 表示选项 "-x" ,选项字符 "x:" 表示选项和其参数 "-x argument",选项字符 "x::" 表示选项 x 的参数是可选的(“::” 是 GNU 增加的,不一定在所有的UNIX 系统下都可以使用)。
    getopt()的返回后,如果有选项参数的话 optarg 指向选项参数,并且变量 optind 包含下一个 argv 参数作为对 getopt() 下一次调用的索引。变量 optopt 保存最后一个由 getopt() 返回的已知的选项。
    当参数列已经到结尾时getopt()函数返回-1,当遇到一个未知的选项时 getopt 返回'?'。参数列中选项的解释可能会被'--'取消,由于它引起 getopt()给参数处理发送结束信号并返回-1。
    很多时候,我们不希望输出任何错误信息,或更希望输出自己定义的错误信息。可以采用以下两种方法来更改getopt()函数的出错信息输出行为:
    在调用getopt()之前,将opterr设置为0,这样就可以在getopt()函数发现错误的时候强制它不输出任何消息。
    如果optstring参数的第一个字符是冒号,那么getopt()函数就会保持沉默,并根据错误情况返回不同字符,如下:
    “无效选项” ―― getopt()返回'?',并且optopt包含了无效选项字符(这是正常的行为)。
    “缺少选项参数” ―― getopt()返回':',如果optstring的第一个字符不是冒号,那么getopt()返回'?',这会使得这种情况不能与无效选项的情况区分开。
    /* getopt.c */
    #include <unistd.h>
    #include <stdio.h>
    int main(int argc, char * argv[])
    {
        int aflag=0, bflag=0, cflag=0;
        int ch;
        while ((ch = getopt(argc, argv, "ab:c")) != -1)
        {
            printf("optind: %d/n", optind);
            switch (ch) {
            case 'a':
                printf("HAVE option: -a/n");
                aflag = 1;
                break;
            case 'b':
                printf("HAVE option: -b/n");
                bflag = 1;
                printf("The argument of -b is %s/n", optarg);
                break;
            case 'c':
                printf("HAVE option: -c");
                cflag = 1;
                break;
            case '?':
                printf("Unknown option: %c/n",(char)optopt);
                break;
            }
        }
    }
    2.getopt_long
    int getopt_long(int argc, char * const argv[],
                      const char *optstring,
                      const struct option *longopts, int *longindex);
    其中我们使用了一个结构体struct options的数组,struct options longopt[].
    struct options的定义如下:
    struct option{
         const char *name;
         int has_arg;
         int *flag;
         int val;
    };
    对结构中的各元素解释如下:
        const char *name
        这是选项名,前面没有短横线。譬如"help"、"verbose"之类。
        int has_arg
        描述了选项是否有选项参数。如果有,是哪种类型的参数,此时,它的值一定是下表中的一个。
        符号常量     数值     含义
        no_argument     0     选项没有参数
        required_argument     1     选项需要参数
        optional_argument     2     选项参数可选
        int *flag
        如果这个指针为NULL,那么 getopt_long()返回该结构val字段中的数值。如果该指针不为NULL,getopt_long()会使得它所指向的变量中填入val字段中的数值,并且getopt_long()返回0。如果flag不是NULL,但未发现长选项,那么它所指向的变量的数值不变。
        int val
        这个值是发现了长选项时的返回值,或者flag不是NULL时载入*flag中的值。典型情况下,若flag不是NULL,那么val是个真/假值,譬如 1或0;另一方面,如果flag是NULL,那么 val通常是字符常量,若长选项与短选项一致,那么该字符常量应该与optstring中出现的这个选项的参数相同。
        每个长选项在长选项表中都有一个单独条目,该条目里需要填入正确的数值。数组中最后的元素的值应该全是0。数组不需要排序,getopt_long()会进行线性搜索。但是,根据长名字来排序会使程序员读起来更容易。
    #include <stdio.h>
    #include <getopt.h>
    int do_name, do_gf_name;
    char *l_opt_arg;
    static const char *shortopts = "l:ng";
    struct option longopts[] = {
      {"name", no_argument, NULL, 'n'},
      {"gf_name", no_argument, NULL, 'g'},
      {"love", required_argument, NULL, 'l'},
      {0, 0, 0, 0},
    };
    int main (int argc, char *argv[])
    {
      int c;
      while ((c = getopt_long (argc, argv, shortopts, longopts, NULL)) != -1)
        {
          switch (c)
        {
        case 'n':
          printf ("My name is LYR./n");
          break;
        case 'g':
          printf ("Her name is BX./n");
          break;
        case 'l':
          l_opt_arg = optarg;
          printf ("Our love is %s!/n", l_opt_arg);
          break;
        }
        }
      return 0;
    }

    具体案例:

    /* getopt_demo - demonstrate getopt() usage
     *
     * This application shows you one way of using getopt() to
     * process your command-line options and store them in a
     * global structure for easy access.
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    /* doc2html supports the following command-line arguments:
     * 
     * -I - don't produce a keyword index
     * -l lang - produce output in the specified language, lang
     * -o outfile - write output to outfile instead of stdout
     * -v - be verbose; more -v means more diagnostics
     * additional file names are used as input files
     * 
     * The optString global tells getopt() which options we
     * support, and which options have arguments.
     */
    struct globalArgs_t {
        int noIndex;                /* -I option */
        char *langCode;                /* -l option */
        const char *outFileName;    /* -o option */
        FILE *outFile;
        int verbosity;                /* -v option */
        char **inputFiles;            /* input files */
        int numInputFiles;            /* # of input files */
    } globalArgs;
    
    static const char *optString = "Il:o:vh?";
    
    /* Display program usage, and exit.
     */
    void display_usage( void )
    {
        puts( "doc2html - convert documents to HTML" );
        /* ... */
        exit( EXIT_FAILURE );
    }
    
    /* Convert the input files to HTML, governed by globalArgs.
     */
    void convert_document( void )
    {
        printf("InputFiles:%d/n",globalArgs.numInputFiles);
        /* ... */
    }
    
    int main( int argc, char *argv[] )
    {
        int opt = 0;
        
        /* Initialize globalArgs before we get to work. */
        globalArgs.noIndex = 0;        /* false */
        globalArgs.langCode = NULL;
        globalArgs.outFileName = NULL;
        globalArgs.outFile = NULL;
        globalArgs.verbosity = 0;
        globalArgs.inputFiles = NULL;
        globalArgs.numInputFiles = 0;
        
        /* Process the arguments with getopt(), then 
         * populate globalArgs. 
         */
        opt = getopt( argc, argv, optString );
        while( opt != -1 ) {
            switch( opt ) {
                case 'I':
                    globalArgs.noIndex = 1;    /* true */
                    break;
                    
                case 'l':
                    globalArgs.langCode = optarg;
                    break;
                    
                case 'o':
                    /* This generates an "assignment from
                     * incompatible pointer type" warning that
                     * you can safely ignore.
                     */
                    globalArgs.outFileName = optarg;
                    break;
                    
                case 'v':
                    globalArgs.verbosity++;
                    break;
                    
                case 'h':    /* fall-through is intentional */
                case '?':
                    display_usage();
                    break;
                    
                default:
                    /* You won't actually get here. */
                    break;
            }
            
            printf("optind=%d/n",optind);
            opt = getopt( argc, argv, optString );
        }
        
        globalArgs.inputFiles = argv + optind;
        globalArgs.numInputFiles = argc - optind;
        printf("argc=%d/n",argc);
        printf("optind=%d/n",optind);
        convert_document();
        
        return EXIT_SUCCESS;
    }
    
    

    作者:gnuhpc
    出处:http://www.cnblogs.com/gnuhpc/


                   作者:gnuhpc
                   出处:http://www.cnblogs.com/gnuhpc/
                   除非另有声明,本网站采用知识共享“署名 2.5 中国大陆”许可协议授权。


    分享到:

  • 相关阅读:
    行转列,列转行
    聚合函数:sum,count,max,avg
    row_number() over partition by 分组聚合
    mysql优化
    hive中not in优化
    DBCP数据库连接池的简单使用
    Eclipse或MyEclipse中给第三方jar包添加源码步骤
    Java中CountDownLatch类的使用
    PLSQL Developer安装、配置、连接oracle数据库
    oracle11g卸载(win10)
  • 原文地址:https://www.cnblogs.com/gnuhpc/p/2807061.html
Copyright © 2020-2023  润新知