• Linux getopt函数的使用


    前言

    getopt()和getopt_long()是用于解析命令行参数的函数,常用于编写命令行工具或应用程序。它们在Linux和其他类Unix系统中非常常见。

    getopt()函数是较旧的函数,而getopt_long()函数是对其进行改进和扩展的版本,提供更灵活的选项解析功能。

    一、getopt函数

    NAME
           getopt - Parse command-line options
    
    SYNOPSIS
           #include 
    
           int getopt(int argc, char * const argv[],
                      const char *optstring);
    
           extern char *optarg;
           extern int optind, opterr, optopt;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    getopt()函数是一个用于解析命令行参数的C标准库函数,常用于Linux和Unix系统中的命令行工具开发。

    getopt()函数会扫描命令行参数,识别出选项字符,并返回这些选项字符。如果选项字符带有参数,则可以使用全局变量optarg来获取参数的值。

    getopt()函数解析命令行参数。它的参数argc和argv是程序调用时传递给main()函数的参数计数和数组。argv中以“-”开头的元素是一个选项元素。此元素的字符(除了首字母“-”之外)是选项字符。如果重复调用getopt(),它将依次返回每个选项元素中的每个选项字符。

    optstring参数是一个包含合法选项字符的字符串:
    (1)每个选项字符表示一个可用的选项。
    (2)如果选项字符后面跟着一个冒号:,则表示该选项需要一个参数。
    (3)如果选项字符后面跟着两个冒号::,表示选项后面带一个可选参数,即参数可有可无, 如果带参数,则选项与参数直接不能有空格形式。

    #include 
    #include 
    
    int main(int argc, char *argv[]) {
        int opt;
    
        while ((opt = getopt(argc, argv, "abc:d::")) != -1) {
            switch (opt) {
                case 'a':
                    printf("Option -a\n");
                    break;
                case 'b':
                    printf("Option -b\n");
                    break;
                case 'c':
                    printf("Option -c with argument: %s\n", optarg);
                    break;            
                case 'd':
                    if (optarg != NULL)
                        printf("Option -d with argument: %s\n", optarg);
                    else
                        printf("Option -d without argument\n");
                    break;
                case '?':
                    printf("Invalid option: %c\n", optopt);
                    break;
            }
        }
    
        return 0;
    }
    
    • 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
    • 28
    • 29
    • 30
    • 31
    # ./a.out -a
    Option -a
    
    # ./a.out -b
    Option -b
    
    # ./a.out -c 111
    Option -c with argument: 111
    
    # ./a.out -d111
    Option -d with argument: 111
    # ./a.out -d 111
    Option -d without argument
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    一个冒号“ :”表示后面必须跟参数,而还有一种表示方式就是两个冒号“ ::”表示这是一个可选参数(可以跟参数,也可以不跟参数,即可选参数)。
    可选参数冒号后边,如果要跟参数, 一定不能加空格。

    二、getopt_long函数

    getopt_long()函数类似于getopt()函数,但它还支持长选项,即以两个破折号(–)开头的选项。

    getopt_long是Linux C程序中的一个函数,用于解析命令行参数。它是一个强大而灵活的函数,可以处理长选项(以"–“开头的选项)和短选项(以”-"开头的选项)。

    长选项的名称可以缩写,前提是缩写是唯一的或与某个定义的选项完全匹配。长选项可以采用两种形式的参数:–arg=param或–arg param。

           #include 
    
           int getopt_long(int argc, char * const argv[],
                      const char *optstring,
                      const struct option *longopts, int *longindex);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    /* Describe the long-named options requested by the application.
       The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
       of 'struct option' terminated by an element containing a name which is
       zero.
    
       The field 'has_arg' is:
       no_argument		(or 0) if the option does not take an argument,
       required_argument	(or 1) if the option requires an argument,
       optional_argument 	(or 2) if the option takes an optional argument.
    
       If the field 'flag' is not NULL, it points to a variable that is set
       to the value given in the field 'val' when the option is found, but
       left unchanged if the option is not found.
    
       To have a long-named option do something other than set an 'int' to
       a compiled-in constant, such as set a value from 'optarg', set the
       option's 'flag' field to zero and its 'val' field to a nonzero
       value (the equivalent single-letter option character, if there is
       one).  For long options that have a zero 'flag' field, 'getopt'
       returns the contents of the 'val' field.  */
    
    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
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    struct option的字段含义如下:
    name:长选项的名称。
    has_arg:指定选项是否带有参数。它可以具有以下值之一:

    no_argument(或0):选项不带参数。
    required_argument(或1):选项需要一个参数。
    optional_argument(或2):选项带有可选参数。
    
    • 1
    • 2
    • 3

    flag:指定长选项的结果如何返回。如果flag为NULL,则getopt_long()返回val。或者,如果flag不为NULL,则getopt_long()返回0,并且flag指向一个变量,如果找到该选项,则将其设置为val,否则保持不变。

    val:要返回的值,或加载到flag指向的变量中。

    longopts数组的最后一个元素应填充为零,以标记其结尾。

    如果longindex参数不为NULL,它将指向一个变量,该变量将被设置为相对于longopts的长选项的索引。

    #include 
    #include 
    
    void print_help() {
        printf("Usage: ./a.out [OPTIONS]\n");
        printf("Options:\n");
        printf("  -h, --help     Display this help message\n");
        printf("  -v, --verbose  Verbose option\n");
        printf("  -i, --input    Input file\n");
        printf("  -o, --output   Optional output file\n");
    }
    
    int main(int argc, char *argv[]) {
        int opt;
        int option_index = 0;
    
        // 定义长选项结构数组
        static struct option long_options[] = {
            {"help", no_argument, NULL, 'h'},
            {"verbose", no_argument, NULL, 'v'},
            {"input", required_argument, NULL, 'i'},
            {"output", optional_argument, NULL, 'o'},
            {NULL, 0, NULL, 0} // 结束标记
        };
    
        while ((opt = getopt_long(argc, argv, "hvi:o:", long_options, &option_index)) != -1) {
            switch (opt) {
                case 'h':
                    print_help();
                    return 0;
                case 'v':
                    printf("Verbose option\n");
                    break;
                case 'i':
                    printf("Input file: %s\n", optarg);
                    break;
                case 'o':
                    if (optarg != NULL)
                        printf("Output file: %s\n", optarg);
                    else
                        printf("Output file not specified\n");
                    break;
                case '?':
                    printf("Invalid option\n");
                    break;
                default:
                    break;
            }
        }
    
        return 0;
    }
    
    • 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
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    (1)

    # ./a.out -h    //--help  
    Usage: ./a.out [OPTIONS]
    Options:
      -h, --help     Display this help message
      -v, --verbose  Verbose option
      -i, --input    Input file
      -o, --output   Optional output file
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    no_argument(或者是0)时,不用跟参数。

    (2)

    # ./a.out -v
    Verbose option
    # ./a.out --verbose
    Verbose option
    
    • 1
    • 2
    • 3
    • 4

    no_argument(或者是0)时,不用跟参数。

    (3)

    # ./a.out -i text
    Input file: text
    
    t# ./a.out --input text
    Input file: text
    
    t# ./a.out --input=text
    Input file: text
    
    # ./a.out --input
    ./a.out: option '--input' requires an argument
    Invalid option
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    备注:required_argument(或者是1)时 长选项–参数输入格式为:

    --参数 值 或者 --参数=--input text 或者 --input=text
    
    • 1

    (4)

    # ./a.out -o text
    Output file: text
    
    # ./a.out --output text
    Output file not specified
    
    # ./a.out --output=text
    Output file: text
    
    # ./a.out --output
    Output file not specified
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    注意:optional_argument(或者是2)时 长选项–参数输入格式只能为:

    --参数=-output=text
    
    • 1

    长选项–参数输入格式才可以不带参数,短选项-参数需要带参数:

    # ./a.out -o
    ./a.out: option requires an argument -- 'o'
    Invalid option
    # ./a.out --output
    Output file not specified
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    CSS3 就可以写出一个苹果官方渐变颜色文字效果,真的太逼真了!
    Apache Lucene 7.0 - 索引文件格式
    网络安全深入学习第一课——热门框架漏洞(RCE-代码执行)
    92.(leaflet篇)leaflet态势标绘-进攻方向采集
    javascript高级(3)
    vue 两种路由模式具体实现
    正则表达式--1(模式分组)
    go install 出现 cannot use path@version syntax in GOPATH mode 的解决办法
    Linux文件管理知识查找文件
    ChatGPT搭建AI网站实战
  • 原文地址:https://blog.csdn.net/weixin_45030965/article/details/136651356