linux命令行参数解析(getopt和getopt_long)

命令行参数

在这里插入图片描述
命令行参数由Command name,Option,Option argument 以及Operands组成。

  • Command name是程序的名称。
  • Operands是操作数。
  • Option是选项,决定程序的执行方式
  • Option argument是选项参数,是Option所需要的信息。

getopt()

1
2
3
4
5
6
7
#include <unistd.h>  
 
int getopt(int argc, char * const argv[],  
           const char *optstring);  
 
extern char *optarg;  
extern int optind, opterr, optopt;
  • 参数argc,argv与main函数保持一致
  • optstring 是选项字符串
  • 返回值为选项字符

选项字符串(optstring):
通过该字符串规定getopt所解析的选项,optstring就是用选项字符以及冒号所组成的.
例如:“a: b::c”

  • 单个字符a,规定在执行程序时必须使用<程序名> -a 其后不能加参数。
  • b:,规定在执行程序时必须使用<程序名> -b <参数> 其后必须加所需的参数,选项参数和选项之间可以有空格也可以没有空格。
  • c::,规定在执行程序时使用 <程序名> -c[参数] 其后可以加参数也可以不加,但是加参数时选项后面不能有空格,否则会认为参数为NULL。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>
#include <unistd.h>

int main(int argc,char* argv[])
{<!-- -->
    int opt;
    char * optstr = "a:b::c";
    //opterr = 0;
    while ((opt=getopt(argc,argv,optstr))!=-1)
    {<!-- -->
        printf("Your option is : -%c\n",opt);
        printf("Your option argument is : %s\n",optarg);
    }
    return 0;
}

测试运行结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

我们再来介绍一下getopt中设置的几个全局变量:

  • char* optarg 指向选项参数,若无选项参数则为NULL。

  • int optind 指向所扫描的命令行参数位置。初始值为1。当你下一次调用getopt时,便从optind的位置开始扫描。

  • int opterr

    • opterr的值非0时,在getopt()遇到无法识别的选项,或者某个选项丢失选项参数的时候,getopt()会打印错误信息到标准错误输出。

    • 例如:-a后未加参数,那么就会提示
      在这里插入图片描述
      输入无法识别选项:
      在这里插入图片描述

    • opterr值为0时,则不打印错误信息。
      在这里插入图片描述
      在这里插入图片描述

  • int optopt 在上述两种错误之一发生时,一般情况下getopt()会返回’?’,并且将optopt赋值为发生错误的选项。

如果想自己处理以上两种错误情况,可以设置optstring的首字符为’:’,

  • 如果出现缺少参数,那么getopt会返回’:’
  • 如果出现无法识别的选项,那么getopt会返回’?’

getopt_long()

使用函数getopt_long

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*在文件getopt_ext.h中有以下声明*/
struct option
{<!-- -->
  const char *name;
  /* has_arg can't be an enum because some compilers complain about
     type mismatches in all the code that assumes it is an int.  */
  int has_arg;
  int *flag;
  int val;
};

/* Names for the values of the 'has_arg' field of 'struct option'.  */
#define no_argument     0
#define required_argument   1
#define optional_argument   2

extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
            const char *__shortopts,const struct option *__longopts, int *__longind)

声明了一个结构体option:

  • name为选项的名称。

  • has_arg表示选项是否带有参数,所以定义了三个常量

    • no_argument 表示该选项无参数。 如: -name (后面不能跟参数)
    • required_argument 表示该选项必须要有参数。如 : -name fy (后面必须跟)
    • optional_argument 表示该选项参数可选。如: -name 或 -name fy 均可
  • flag 如果设置为NULL,当选中某个长选项时则返回val的值。如果flag不为空,那么当选中某个长选项时,getopt_long将会返回0,将flag指向val。

  • val就是找到该长参数时getopt_long的返回值,如果扫描的是此长参数,那么返回的就是该参数的val。可以理解为该长参数的代号。

    getopt_long的各个参数:

    • shortopts:为短选项字符串,同getopt中的optstr
    • longopts:为长选项opt结构体
    • longindex:longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>


int main(int argc,char* argv[])
{<!-- -->
    char* optstring="a:b::c";
    int opt;
    struct option long_options[]=
    {<!-- -->
        {<!-- -->"Firstname",required_argument,NULL,'F'},
        {<!-- -->"Lastname",required_argument,NULL,'L'},
        {<!-- -->"Age",optional_argument,NULL,'A'}
    };

   while ( (opt = getopt_long(argc, argv, optstring, long_options, 0)) != -1)
   {<!-- -->
        printf("opt = %c\n", opt);
        printf("optarg = %s\n", optarg);
        printf("optind = %d\n", optind);
       
   }
   
   return 0;
 
}

演示结果:
在这里插入图片描述