zoukankan      html  css  js  c++  java
  • getopt函数的使用——分析命令行参数

    getopt(分析命令行参数)

    • 相关函数表头文件
      #include<unistd.h>
    • 函数声明
      int getopt(int argc,char * const argv[ ],const char * optstring);
    • 全局变量

        extern char *optarg;

        extern int optind, opterr, optopt;  //索引/错误输出标志/最后一个未知选项

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

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

    char *optarg——当前选项参数字串(如果有)。

    int optind——argv的当前索引值。当getopt()在while循环中使用时,循环结束后,剩下的字串视为操作数,在argv[optind]至argv[argc-1]中可以找到。

    int opterr——这个变量非零时,getopt()函数为“无效选项”和“缺少参数选项,并输出其错误信息。

    int optopt——当发现无效选项字符之时,getopt()函数或返回'?'字符,或返回':'字符,并且optopt包含了所发现的无效选项字符。

    短参数的定义

    getopt()使用optstring所指的字串作为短参数列表,象"1ac:d::"就是一个短参数列表。短参数的定义是一个-后面跟一个字母或数字,象-a,-b就是一个短参数。每个数字或字母定义一个参数。

    其中短参数在getopt定义里分为三种:

    1、不带值的参数,它的定义即是参数本身。

    2、必须带值的参数,它的定义是在参数本身后面再加一个冒号。

    3、可选值的参数,它的定义是在参数本身后面加两个冒号 。

    在这里拿上面的"1ac:d::"作为样例进行说明,其中的1,a就是不带值的参数,c必须带值的参数,d可选值的参数。
      在实际调用中,-1 -a -c cvalue -d, -1 -a -c cvalue -ddvalue,-1a -ddvalue -c cvalue都是合法的。这里需要注意三点:

    1、不带值的参数可以连写,象1a是不带值的参数,它们可以-1 -a分开写,也可以-1a-a1连写。

    2、参数不分先后顺序,-1a -c cvalue -ddvalue-d -c cvalue -a1的解析结果是一样的。

    3、要注意可选值的参数的参数之间不能有空格,必须写成-ddvalue这样的格式,如果写成-d dvalue这样的格式就会解析错误。

    默认情况下getopt会重新排列命令行参数的顺序,所以到最后所有不包含选项的命令行参数都排到最后。

    返回值

    getopt()每次调用会逐次返回命令行传入的参数。
    没有参数的最后的一次调用时,getopt()将返回-1
    当解析到一个不在optstring里面的参数,或者一个必选值参数不带值时,返回?
    当optstring是以:开头时,缺值参数的情况下会返回:,而不是?

    范例

     1 #include <unistd.h>
     2 #include <stdlib.h>
     3 #include <stdio.h>
     4 
     5 int
     6 main(int argc, char *argv[])
     7 {
     8     int opt;    /*接收选项*/
     9     extern char* optarg;/*指向当前getopt()返回选项的参数*/
    10     extern int optopt;  /*当选项没有出现在optstring中,或者选项缺少必要的参数时,该选项存储在optopt中,getopt返回'?’*/
    11     extern int opterr;  /*用于控制getopt()是否打印出错信息*/
    12     extern int optind;  /*当前getopt()返回选项的下一个选项的索引(argv数组)*/
    13 
    14     opterr = 0; /*不要打印出错信息*/
    15 
    16     while ((opt = getopt(argc, argv, "a1b:c::")) != -1) {
    17         /* a和1为不带参数选项,b为必须带一个参数选项,c为可选参数选项(注意参数与-c直接不能分开) */
    18         /* 示例: getopt -a -b 100 -c12 */
    19         switch (opt) {
    20             case 'a':
    21             case '1':
    22                 printf("选项: %c
    ",opt);
    23                 break;
    24             case 'b':
    25                 printf("选项: b,带的参数是 %s
    ",optarg);
    26                 break;
    27             case 'c':
    28                 printf("选项: c,带的参数是 %s
    ",optarg);
    29                 break;
    30             default: /* '?' */
    31                 if(optopt == 'c'){
    32                     printf("选项: c,没有带参数
    ");
    33                     break;
    34                 }
    35                 fprintf(stderr, "用法: %s [-1a] [-c [argument]] [-b argument]
    ",
    36                             argv[0]);
    37                 exit(EXIT_FAILURE); //无效的参数,退出程序
    38         }
    39     }
    40     printf("optind=%d
    ",optind);
    41 
    42     //在命令行选项参数再也检查不到optstring中包含的选项时,
    43     //返回-1,同时optind储存第一个不包含选项的命令行参数。
    44     //getopt 中指的 选项是指以 `-`开头的
    45     if (optind >= argc) {
    46         fprintf(stderr, "选项索引超过了argv数组的长度
    ");
    47         exit(EXIT_FAILURE);
    48     }
    49     //输出第一个不包含选项的参数
    50     printf("非选项参数 = %s
    ", argv[optind]);
    51 
    52     //输出一下命令行参数,看看是否被改变
    53     for(opt = 0; opt < argc ; ++opt){
    54         printf("索引:%d		命令行参数:%s
    ",opt,argv[opt]);
    55     }
    56 
    57     exit(EXIT_SUCCESS); //成功退出
    58 }
    getopt示例代码

    执行:

    fx@fx:~/code$ ./getopt -a -b 100 -c12
    选项: a
    选项: b,带的参数是 100
    选项: c,带的参数是 12
    optind=5
    选项索引超过了argv数组的长度
    fx@fx:~/code$ ./getopt -a 哈哈 -b 100 -c12 
    选项: a
    选项: b,带的参数是 100
    选项: c,带的参数是 12
    optind=5
    非选项参数 = 哈哈
    索引:0        命令行参数:./getopt
    索引:1        命令行参数:-a
    索引:2        命令行参数:-b
    索引:3        命令行参数:100
    索引:4        命令行参数:-c12
    索引:5        命令行参数:哈哈

    getopt_long示例代码

     1 #include <unistd.h>
     2 #include <stdlib.h>
     3 #include <stdio.h>
     4 
     5 extern int optind, opterr, optopt;
     6 
     7 int
     8 main(int argc, char **argv)
     9 {
    10     int c;  /* 用于接收字符选项 */
    11     int digit_optind = 0;   /* 用于接收数字选项 */
    12 
    13     while (1) {
    14         /* */
    15         int this_option_optind = optind ? optind : 1;
    16         int option_index = 0;
    17         /* 长选项结构体数组 */
    18         static struct option long_options[] = {
    19             {"add",     required_argument, 0,  0 }, //需要一个参数
    20             {"append",  no_argument,       0,  0 }, //没有参数
    21             {"delete",  required_argument, 0,  0 },
    22             {"verbose", no_argument,       0,  0 },
    23             {"create",  required_argument, 0, 'c'}, //返回字符'c'
    24             {"file",    required_argument, 0,  0 },
    25             {0,         0,                 0,  0 }
    26         };
    27 /*
    28         struct option {
    29             const char *name; //选项名称
    30             int         has_arg;    //参数标志(no_argument/0没有参数;required_argument/1需要一个参数;optional_argument/2一个可选参数)
    31             int        *flag;   //指定如何返回一个较长的选项。当这个指针为空的时候,函数直接将val的数值从getopt_long的返回值返回出去,当它非空时,val的值会被赋到flag指向的整型数中,而函数返回值为0
    32             int         val;    //用于指定函数找到该选项时的返回值,或者当flag非空时指定flag指向的数据的值。
    33         };
    34 */
    35         /* 获取一个选项 */
    36         c = getopt_long(argc, argv, "abc:d:012",
    37                     long_options, &option_index);
    38 
    39         if (c == -1){   /* 无参数可获取了 */
    40           break;
    41         }
    42 
    43         switch (c) {    /* 获取参数解析 */
    44             case 0:
    45                 printf("选项是:%s", long_options[option_index].name);
    46                 if (optarg){    /*如果是带参数的选项 */
    47                   printf(" 参数是: %s", optarg);
    48                 }
    49                 printf("
    ");
    50                 break;
    51 
    52             case '0':
    53             case '1':
    54             case '2':
    55                 if (digit_optind != 0 && digit_optind != this_option_optind)
    56                   printf("digits occur in two different argv-elements.
    ");
    57                 digit_optind = this_option_optind;
    58                 printf("选项: %c
    ", c);
    59                 break;
    60 
    61             case 'a':
    62                 printf("选项: a
    ");
    63                 break;
    64 
    65             case 'b':
    66                 printf("选项: b
    ");
    67                 break;
    68             case 'c':
    69                 printf("选项: c 带的值: '%s'
    ", optarg);
    70                 break;
    71 
    72             case 'd':
    73                 printf("选项: d 带的值: '%s'
    ", optarg);
    74                 break;
    75 
    76             case '?':
    77                 break;
    78 
    79             default:
    80                 printf("?? getopt 返回字符代码 0%o ??
    ", c);
    81         }
    82     }
    83 
    84     if (optind < argc) {
    85         printf("非选项的命令行参数项: ");
    86         while (optind < argc)
    87           printf("%s ", argv[optind++]);
    88         printf("
    ");
    89     }
    90     exit(EXIT_SUCCESS);
    91 }
    getopt_long示例代码
  • 相关阅读:
    基于 Docker 的 MySQL 主从复制搭建
    获取 Docker 容器的 IP 地址
    Maven 学习资料
    docker 中,修改了 mysql 配置,如何重启 mysql?
    TiDB 学习资料
    Sharding-JDBC 学习资料
    Druid(数据库连接池) 学习资料
    JWT 学习资料
    Maven 拥有三套相互独立的生命周期:clean、default、site
    Maven 生命周期的阶段与插件的目标之间的绑定关系
  • 原文地址:https://www.cnblogs.com/oloroso/p/4616282.html
Copyright © 2011-2022 走看看