当前位置: 代码迷 >> 综合 >> 命令行解析函数(getopt,getopt_long,getopt_long_only)
  详细解决方案

命令行解析函数(getopt,getopt_long,getopt_long_only)

热度:53   发布时间:2023-12-06 14:08:19.0

命令行解析函数

参考:
https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html#Using-Getopt
https://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Options.html
https://linux.die.net/man/3/getopt_long
这里主要整理翻译了一下,并给出了例程。

#include <unistd.h>int getopt(int argc, char * const argv[],const char *optstring);// 返回值变量,系统声明的全局变量
extern char *optarg;
extern int optind, opterr, optopt;#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);

getopt

  1. The getopt() function parses the command-line arguments. Its arguments argc and argv are the argument count and array as passed to the main() function on program invocation. An element of argv that starts with ‘-’ (and is not exactly “-” or “–”) is an option element. getopt处理短选项,以’-‘为开头的。比如’-h’,而不能处理’–help’。

  2. 参数

    • argc : main()函数传递过来的参数个数
    • argv : main()函数传递过来的参数的字符串指针数组
    • opstring : 选项字符串,字符串格式:“ab:c::”
      • 无冒号,表示没有参数,如’-a’
      • 一个冒号,表示必须有参数,如’-b100’或’-b 100’
      • 两个冒号,可以有参数,也可以没有
  3. 返回值:

    If an option was successfully found, then getopt() returns the option character.

    If all command-line options have been parsed, then getopt() returns -1.

    If getopt() encounters an option character that was not in optstring, then ‘?’ is returned.

    If getopt() encounters an option with a missing argument, then the return value depends on the first character in optstring: if it is ‘:’, then ‘:’ is returned; otherwise ‘?’ is returned.

    如果成功找到选项则返回选项对应字符。

    如果所有选项已经解析完毕,返回 -1 。

    如果发现不存在的选项返回’?’ 。

    如果发现缺少参数,如果是需要参数的选项则返回’:‘而不是’?’。

  4. 返回的参数:

    • optind : This variable is set by getopt to the index of the next element of the argv array to be processed. Once getopt has found all of the option arguments, you can use this variable to determine where the remaining non-option arguments begin. The initial value of this variable is 1. 要处理的下一个元素在argv中的位置,系统的初始值为1,在使用时可重置为1 。

    • opterr : If the value of this variable is nonzero, then getopt prints an error message to the standard error stream if it encounters an unknown option character or an option with a missing required argument. This is the default behavior. If you set this variable to zero, getopt does not print any messages, but it still returns the character ? to indicate an error.如果不需要输出错误信息,可将opterr设置为0 。

    • optopt : When getopt encounters an unknown option character or an option with a missing required argument, it stores that option character in this variable. You can use this for providing your own diagnostic messages. 在识别到未知选项的时候将未知的选项存入optopt。

    • optarg : This variable is set by getopt to point at the value of the option argument, for those options that accept arguments. 指向能够识别的选项参数(对于有参数的选项)。

  5. 测试代码:

    #include <stdio.h>
    #include <unistd.h>
    #include <getopt.h>int main(int argc, char *argv[]) {
          int opt;// 设置为0时不输出错误信息// opterr = 0;while((opt = getopt(argc, argv, "ab:c::")) != -1) {
          printf("opt = %c\t\t", opt);printf("optarg = %s\t\t",optarg);printf("optind = %d\t\t",optind);printf("argv[optind] = %s\n",argv[optind]);}return 0;
    }
    
  6. 测试结果:

    输入错误选项

    ./a.out -a -b100 -c100 -e
    opt = a         optarg = (null)         optind = 2              argv[optind] = -b100
    opt = b         optarg = 100            optind = 3              argv[optind] = -c100
    opt = c         optarg = 100            optind = 4              argv[optind] = -e
    ./a.out: invalid option -- 'e'
    opt = ?         optarg = (null)         optind = 5              argv[optind] = (null)
    

    不输入必须参数

    ./a.out -a -b -c100 
    opt = a         optarg = (null)         optind = 2              argv[optind] = -b
    opt = b         optarg = -c100          optind = 4              argv[optind] = (null)
    

getopt_long

  1. To accept GNU-style long options as well as single-character options, use getopt_long instead of getopt. This function is declared in getopt.h, not unistd.h. You should make every program accept long options if it uses any options, for this takes little extra work and helps beginners remember how to use the program. 既可以处理长选项,也可以处理短选项。

  2. 参数:

    • longopts : The argument longopts must be an array of option structures.

      一个option结构体数组。

    • longindex : If longindex is not NULL, it points to a variable which is set to the index of the long option relative to longopts.

      longopts的下标。

  3. 数据结构:

    struct option {
          const char *name;int         has_arg;int        *flag;int         val;
    };
    
  4. 数据结构参数:

    • name : This field is the name of the option. It is a string.

      选项名称

    • has_arg : This field says whether the option takes an argument. It is an integer, and there are three legitimate values: no_argument, required_argument and optional_argument.

      表示是否有参数。可以为3个值:no_argument, required_argumentoptional_argument。分别表示不带参数,必须带参数,可以带参数,与短选项相一致。

    • flag : specifies how results are returned for a long option. If flag is NULL, then getopt_long() returns val. Otherwise, getopt_long() returns 0, and flag points to a variable which is set to val if the option is found, but left unchanged if the option is not found.

      长选项的返回方式。如果flag为NULL,那么返回参数val,否则flag指向所找到的选项(没找到则不改变)。

    • val : These fields control how to report or act on the option when it occurs.

      If flag is a null pointer, then the val is a value which identifies this option. Often these values are chosen to uniquely identify particular long options.

      If flag is not a null pointer, it should be the address of an int variable which is the flag for this option. The value in val is the value to store in the flag to indicate that the option was seen.

      与flag有关,如果flag为NULL,则val表示的是选项,否则,val则表示地址。

  5. 返回值:对于短选项,返回值同getopt函数;对于长选项,如果flag是NULL,返回val,否则返回0;对于错误情况返回值同getopt函数。

  6. 测试代码:

    #include <stdio.h>
    #include <unistd.h>
    #include <getopt.h>int main(int argc, char *argv[]) {
          int opt;int digit_optind = 0;int option_index = 0;static struct option long_options[] = {
            {
          "rarg", required_argument, NULL, 'r'},{
          "oarg", optional_argument, NULL, 'o'},{
          "narg", no_argument, NULL, 'n'},{
          NULL, 0, NULL, 0},};while((opt =getopt_long(argc, argv, "ab:c::", long_options, &option_index))!= -1) {
          printf("opt = %c\t\t", opt);printf("optarg = %s\t\t",optarg);printf("optind = %d\t\t",optind);printf("argv[optind] =%s\t\t", argv[optind]);printf("option_index = %d\n",option_index);}  
    }
    
  7. 测试结果:

    ./a.out --rarg 100 --oarg --narg
    opt = r         optarg = 100            optind = 3              argv[optind] =--oarg            option_index = 0
    opt = o         optarg = (null)         optind = 4              argv[optind] =--narg            option_index = 1
    opt = n         optarg = (null)         optind = 5              argv[optind] =(null)            option_index = 2
    

getopt_long_only

  1. 将所有的选项都当做长选项,即’-a’也当做’–a’,其他和 getopt_long 一致。