***************************************************************************************************************************
作者:EasyWave                                                                                 时间:2012.07.28

类别:linux应用之mjpg-streamer分析                                         声明:转载,请保留链接

注意:如有错误,欢迎指正。这些是我学习的日志文章......

***************************************************************************************************************************

        在mjpg-streamer的程序中,经常会看到getopt_long_only这个函数,这是一个抓取或者说是解析命令行参数的一个linux下的API函数。主要分为下面几种:

#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);

说明:函数中的argc 和argv 通常直接从main()到两个参数传递而来。optstring 是选项参数组成的字符串,如果该字符串里任一字母后有冒号,那么这个选项就要求有参数。下一个参数是指向数组的指针,这个数组是option 结构数组,option 结构称为长选项表,其声明如下:

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


结构中的元素解释如下:

const char *name:选项名,前面没有短横线。譬如"help"、"input"之类。
int has_arg:描述长选项是否有选项参数,如果有,是哪种类型的参数,其值见下表:
                         符号常量                       数值                含义
                         no_argument                 0            选项没有参数
                         required_argument      1            选项需要参数
                         optional_argument       2           选项参数是可选的
int *flag:
如果该指针为NULL,那么getopt_long 返回val 字段的值;如果该指针不为NULL,那么会使得它所指向的结构填入val 字段的值,同时getopt_long返回0
int val:
如果flag 是NULL,那么val 通常是个字符常量,如果短选项和长选项一致,那么该字符就应该与optstring 中出现的这个选项的参数相同;最后一个参数:longindex 参数一般赋为NULL 即可;如果没有设置为NULL,那么它就指向一个变量,这个变量会被赋值为寻找到的长选项在longopts 中的索引值,这可以用于误诊断。


getopt_long()函数使用规则:
(1)使用前准备两种数据结构
字符指针型变量该数据结构包括了所有要定义的短选项,每一个选项都只用单个字母表示。如果该选项需要参数(如,需要文件路径等),则其后跟一个冒号。例如,三个短选项分别为‘-s’‘-h’‘-v’,其中-o 需要参数,其他两个不需要参数。那么,我们可以将数据结构定义成如下形式:
    const char * const shor_options = “sh:v” ;
     struct option 类型数组
该数据结构中的每个元素对应了一个长选项,并且每个元素是由四个域组成。通常情况下,可以按以下规则使用。第一个元素,描述长选项的名称;第二个选项,代表该选项是否需要跟着参数,需要参数则为1,反之为0;第三个选项,可以赋为NULL;第四个选项,是该长选项对应的短选项名称。另外,数据结构的最后一个元素,要求所有域的内容均为0,即{NULL,0,NULL,0}。下面举例说明,该数据结构可以定义成如下形式:

static struct option long_options[] = \
    {
      {"h", no_argument, 0, 0},
      {"help", no_argument, 0, 0},
      {"i", required_argument, 0, 0},
      {"input", required_argument, 0, 0},
      {"o", required_argument, 0, 0},
      {"output", required_argument, 0, 0},
      {"v", no_argument, 0, 0},
      {"version", no_argument, 0, 0},
      {"b", no_argument, 0, 0},
      {"background", no_argument, 0, 0},
      {0, 0, 0, 0}
    };


在mjpg-streamer的主函数main中有这样一段代码如下:

/* parameter parsing */
  while(1) {
    int option_index = 0, c=0;
    static struct option long_options[] = \
    {
      {"h", no_argument, 0, 0},
      {"help", no_argument, 0, 0},
      {"i", required_argument, 0, 0},
      {"input", required_argument, 0, 0},
      {"o", required_argument, 0, 0},
      {"output", required_argument, 0, 0},
      {"v", no_argument, 0, 0},
      {"version", no_argument, 0, 0},
      {"b", no_argument, 0, 0},
      {"background", no_argument, 0, 0},
      {0, 0, 0, 0}
    };

    c = getopt_long_only(argc, argv, "", long_options, &option_index);

    /* no more options to parse */
    if (c == -1) break;

    /* unrecognized option */
    if(c=='?'){ help(argv[0]); return 0; }

    switch (option_index) {
      /* h, help */
      case 0:
      case 1:
        help(argv[0]);
        return 0;
        break;

      /* i, input */
      case 2:
      case 3:
        input = strdup(optarg);
        break;

      /* o, output */
      case 4:
      case 5:
        output[global.outcnt++] = strdup(optarg);
        break;

      /* v, version */
      case 6:
      case 7:
        printf("MJPG Streamer Version: %s\n" \
               "Compilation Date.....: %s\n" \
               "Compilation Time.....: %s\n", SOURCE_VERSION, __DATE__, __TIME__);
        return 0;
        break;

      /* b, background */
      case 8:
      case 9:
        daemon=1;
        break;

      default:
        help(argv[0]);
        return 0;
    }
  }


重点分析一下getopt_long_only 函数:
int getopt_long_only(int argc, char * const argv[],const char *optstring,const struct option*longopts, int *longindex);
该函数每解析完一个选项,就返回该选项字符。如果选项带参数,参数保存在optarg 中。如果选项带可选参数,而实际无参数时,optarg为NULL。当遇到一个不在optstring 指明的选项时,返回字符'?'。如果在optstring 指明某选项带参数而实际没有参数时,返回字符'?'或者字符':',视optstring 的第一个字符而定。这两种情况选项的实际值被保存在optopt 中。当解析错误时,如果opterr 为1 则自动打印一条错误消息(默认),否则不打印。当解析完成时,返回-1。每当解析完一个argv,optind 就会递增。如果遇到无选项参数,getopt 默认会把该参数调后一位,接着解析下一个参数。如果解析完成后还有无选项的参数,则optind 指示的是第一个无选项参数在argv 中的索引。最后一个参数longindex 在函数返回时指向被搜索到的选项在longopts 数组中的下标。longindex 可以为NULL,表明不需要返回这个值

 

 

Logo

更多推荐