自学内容网 自学内容网

C++可执行文件参数解析

前言

针对简单工程甚至是单cpp文件,C++可执行二进制的参数获取,getopt被用来解析命令行选项参数。该接口在unix的头文件<unistd.h>中定义。参数类型区分为短参数(只有一个中划线’-')、长参数(有2个中划线‘–’),接口函数不同。另外我们也可以采用第三方库来实现参数解析。下面逐一介绍。

getopt短参数解析

短参数是指二进制的参数以‘-’为开始的参数形式。例如:.\paras.exe -o /a/b/c -d 123 -v 2。注意参数和参数值之间没有‘=’符号,是空格。
接口原型: int getopt(int argc, char *const argv[], const char *optstring, int *ind);
说明:
+ int argc:从 main 函数传入的参数数量。
+ char *const argv[]:从 main 函数传入的参数数组。
+ const char *optstring:选项字符串,用于指定哪些选项是有效的。
+ int *ind:可选参数,用于记录解析的位置。
使用方法:

#include <stdio.h>
#include <unistd.h>

namespace
{
    // short getopt example with three parameters, just like "hvo".not support "--" long options.
    // input:  .\paras.exe -o /a/b/c -d 123 -v 2
    // output: 
    //      Output file set to /a/b/c
    //      depth set to 123
    //      Version set to 2
    int ExplainParametersWithoutGetOpt(int argc, char **argv)
    {
        int ret = 0;
        int option;
        while ((option = getopt(argc, argv, "hv:o:d:")) != -1) {
            switch (option) {
                case 'h':
                    printf("Help option selected.\n");
                    break;
                case 'v':
                    printf("Version set to %s\n", optarg);
                    break;
                case 'o':
                    printf("Output file set to %s\n", optarg);
                    break;
                case 'd':
                    printf("depth set to %s\n", optarg);
                    break;
                case '?':
                    printf("Unknown option '%c'.\n", optopt);
                    ret = 1;
                    break;
                default:
                    printf("Unknown option.\n");
                    ret = 1;
                    break;
            }
        }
        return ret;
    }
}

int main(int argc, char **argv)
{
    int ret = ExplainParametersWithoutGetOpt(argc, argv);
    return ret;
}

getopt_long长参数解析

getopt_long不但支持短参还支持长参解析。
长参数是指二进制的参数以‘–’(2个短横)为开始的参数形式。
**接口原型:**int getopt_long(int argc, char *const argv[], const char *shortopts,
const struct option *longopts, int *longindex);
接口参数:

  • argc 和 argv:这两个参数与 main 函数中的参数一致,分别表示命令行参数的数量和参数数组。
  • shortopts:这是一个字符串,表示短选项的格式。例如,“ab:c::” 表示 a 是无参数选项,b 是带必需参数的选项,c 是带可选参数的选项。
  • longopts:这是一个指向 struct option 数组的指针,用于定义长选项的格式。每个 struct option 结构体包含以下字段: name:长选项的名称。
  • has_arg:指示选项是否带参数,0 表示无参数,1 表示必需参数,2
    表示可选参数。
  • flag:如果为 NULL,则 getopt_long 返回 val;否则,返回 0,并将 val 存储到 flag
    指向的变量中。
  • val:将要返回的值或存储到 flag 指向的变量中的值。
  • longindex:这是一个指向整数的指针,用于返回长选项在 longopts 数组中的索引。通常设置为 NULL。

返回值
如果遇到有效的短选项或长选项,getopt_long 返回该选项的字符(对于短选项)或 val(对于长选项)。如果所有选项都已处理完毕,返回 -1。
使用方法:

#include <cstdio>
#include <getopt.h>
#include <unistd.h>

static struct option long_options[] = {
    {"help", no_argument, nullptr, 'h'},
    {"version", required_argument, nullptr, 'v'},
    {"output", required_argument, nullptr, 'o'},
    {0, 0, 0, 0}
};

int main(int argc, char *argv[]) {
    int option_index = 0;
    int c;
    int ret = 0;
    // binary execute: .\longgetopt.exe --version 2 --output d:\temp or .\longgetopt.exe -v 2 -o d:\temp
    // output: 
    //      Verbosity set to 2
    //      Output file set to d:\temp
    while ((c = getopt_long(argc, argv, "hv:o:", long_options, &option_index)) != -1) {
        switch (c) {
            case 'h':
                printf("Help option selected.\n");
                break;
            case 'v':
                printf("Verbosity set to %s\n", optarg);
                break;
            case 'o':
                printf("Output file set to %s\n", optarg);
                break;
            case '?':
                printf("Unknown option '%c'.\n", optopt);
                ret = 1;
                break;
            default:
                printf("Unknown option.\n");
                ret = 1;
                break;
        }
    }
    return ret;
}

第三方库getopt解析

github有一个2016年的工程getopt, 封装了getopt,直接头文件引用就可以了。遗憾的是8年了没有更新。但学习C++参数解析够用了。
克隆代码到demo目录,目录层级如下;

$ tree -l
.paras
|-- paras.cpp
`-- thirdparty
    `-- getopt
        |-- README.md
        |-- demo.cc
        |-- getopt.cpp
        `-- getopt.hpp

应用代码:

#include <iostream>
// #include <string>
#include "thirdparty/getopt/getopt.hpp"

namespace
{
    void ExplainParametersWithGetOpt()
    {
        // - No initialization required: (argc, argv) pair automatically retrieved.
        // - First argument is default option value, then all option indentifiers follow.
        //  binary execute: .\paras.exe -o=/a/b/c -d=123 -v=2
        // output: 0,/a/b/c,123,2
        bool help = getarg(false, "-h", "--help", "-?");
        int version = getarg(0, "-v", "--version", "--show-version");
        int depth = getarg(1, "-d", "--depth", "--max-depth");
        std::string file = getarg("", "-o", "--outputfile");
        std::cout << help << ',' << file << ',' << depth << ',' << version << std::endl;
    }
}

int main()
{
    std::cout << "Explain parameters with getopt lib" << std::endl;
    ExplainParametersWithGetOpt();
    return 0;
}

使用分析:第三方库getopt参数是短参接‘=‘,再接参数值形式。‘=‘不能省。少了一些全局变量。

总结

对于指定二进制或单个cpp,最终二进制启动参数的解析可以使用多种方法,看你的使用习惯。一般长短参都支持,程序的友好性较高。第三方包功能单一,若有更高需要,可以自己扩充。

参考文献

[1] getopt与getopt_long, slmmlk2011_2
h,ttps://blog.csdn.net/slmmlk2011_2/article/details/7964218?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7EPaidSort-1-7964218-blog-142920234.235%5Ev43%5Epc_blog_bottom_relevance_base2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7EPaidSort-1-7964218-blog-142920234.235%5Ev43%5Epc_blog_bottom_relevance_base2&utm_relevant_index=2


原文地址:https://blog.csdn.net/lhb_0531/article/details/144699109

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!