天天看點

C++ 指令行參數解析

文章目錄

    • 說明
    • 短參數之 getopt()
    • 長參數之 getopt_long()
    • 長參數之 getopt_long_only()

說明

主要參考以下部落格:

部落格一:getopt和getopt_long函數
部落格二:C++中如何自定義指令行參數——完整執行個體示範
部落格三:使用 Qt 解析指令行參數
部落格四:linux c/c++中getopt的使用

短參數之 getopt()

頭檔案:#include <unistd.h>

函數原型:int getopt(int argc, char * const argv[], const char *optstring);

參數解釋:

[param1] argc: main 函數的 argc

[param2] argv: main 函數的 argv

[param3] optstring: 格式控制符。"ab:c:d"代表 -b 和 -b 後面必須跟一個參數,而 -a 和 -d 不需要參數

相關變量:

extern char *optarg; 表示參數的具體内容

extern int optind; 表下一個将被處理到的參數在 argv 中的下标值

extern int opterr;

extern int optopt;

測試案例:

// Opt.cpp
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

// 短參數測試案例
void testGetOpt(int argc, char *argv[]) {
    int opt;  // getopt() 的傳回值
    const char *optstring = "a:b:c:d"; // 設定短參數類型及是否需要參數

    while ((opt = getopt(argc, argv, optstring)) != -1) {
        printf("opt = %c\n", opt);  // 指令參數,亦即 -a -b -c -d
        printf("optarg = %s\n", optarg); // 參數内容
        printf("optind = %d\n", optind); // 下一個被處理的下标值
        printf("argv[optind - 1] = %s\n\n",  argv[optind - 1]); // 參數内容
    }
}

int main(int argc, char *argv[]) {
    testGetOpt(argc, argv);
    return 0;
}
           

正确的使用方法(√):

[[email protected]:~/Desktop]$ opt.exe -a a_para -b b_para -c c_para -d	# 參數全用
[[email protected]:~/Desktop]$ opt.exe -a a_para -b b_para -d				# 部分參數
[[email protected]:~/Desktop]$ opt.exe -b b_para -a a_para				# 可以倒序
[[email protected]:~/Desktop]$ opt.exe  									# 可以無參
           

錯誤的使用方法(×):

[[email protected]:~/Desktop]$ opt.exe -a  					# -a 後面沒有跟參數
[[email protected]:~/Desktop]$ opt.exe -a a_para -d d_para  	# -d 後面跟了參數
           

長參數之 getopt_long()

頭檔案:#include <getopt.h>

函數原型:int getopt(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);

參數解釋:

[param1] argc: main 函數的 argc

[param2] argv: main 函數的 argv

[param3] optstring: 格式控制符

[param4] longopts: 一個由option結構體組成的數組,數組的每個元素,指明了一個“長參數”(即形如–name的參數)名稱和性質

[param5] longindex: 如果longindex非空,它指向的變量将記錄目前找到參數符合longopts裡的第幾個元素的描述,即是longopts的下标值

相關變量:

同上

測試案例:

// Opt.cpp
#include <stdlib.h>
#include <stdio.h>
#include <getopt.h>

// 長參數測試案例
void testGetOptLong(int argc, char *argv[]) {
    int opt; // getopt_long() 的傳回值
    int digit_optind = 0; // 設定短參數類型及是否需要參數

    // 如果option_index非空,它指向的變量将記錄目前找到參數符合long_opts裡的
    // 第幾個元素的描述,即是long_opts的下标值
    int option_index = 0;
    // 設定短參數類型及是否需要參數
    const char *optstring = "ab:nr:";  

    // 設定長參數類型及其簡寫,比如 --reqarg <==>-r
    /*
    struct option {
             const char * name;  // 參數的名稱
             int has_arg; // 是否帶參數值,有三種:no_argument, required_argument,optional_argument
             int * flag; // 為空時,函數直接将 val 的數值從getopt_long的傳回值傳回出去,
                     // 當非空時,val的值會被賦到 flag 指向的整型數中,而函數傳回值為0
             int val; // 用于指定函數找到該選項時的傳回值,或者當flag非空時指定flag指向的資料的值
        };
    其中:
        no_argument(即0),表明這個長參數不帶參數(即不帶數值,如:--name)
            required_argument(即1),表明這個長參數必須帶參數(即必須帶數值,如:--name Bob)
            optional_argument(即2),表明這個長參數後面帶的參數是可選的,(即--name和--name Bob均可)
     */
    static struct option long_options[] = {
        {"reqarg", required_argument, NULL, 'r'},
        {"noarg",  no_argument,       NULL, 'n'},
        {"optarg", optional_argument, NULL, 'o'},
        {0, 0, 0, 0}  // 添加 {0, 0, 0, 0} 是為了防止輸入空值
    };

    while ( (opt = getopt_long(argc,
                               argv,
                               optstring,
                               long_options,
                               &option_index)) != -1) {
        printf("opt = %c\n", opt); // 指令參數,亦即 -a -b -n -r
        printf("optarg = %s\n", optarg); // 參數内容
        printf("optind = %d\n", optind); // 下一個被處理的下标值
        printf("argv[optind - 1] = %s\n",  argv[optind - 1]); // 參數内容
        printf("option_index = %d\n", option_index);  // 目前列印參數的下标值
        printf("\n");
    }
}

int main(int argc, char *argv[]) {
    testGetOptLong(argc, argv);
    return 0;
}
           

正确的使用方法(√):

[[email protected]:~/Desktop]$ opt.exe -a -b b_para -n -r r_para					# 全部使用
[[email protected]:~/Desktop]$ opt.exe -a											# 部分參數
[[email protected]:~/Desktop]$ opt.exe -a -b b_para								# 部分參數
[[email protected]:~/Desktop]$ opt.exe -a -b b_para -n							# 部分參數
[[email protected]:~/Desktop]$ opt.exe -n -r r_para								# 部分參數
[[email protected]:~/Desktop]$ opt.exe  -a --noarg --reqarg required_para			# 長參數
           

錯誤的使用方法(×):

注意事項:一般地,不要将短參數的 optstring 和長參數的 struct option 的 val 設定為一樣的字母,這樣易于區分!!!

長參數之 getopt_long_only()

頭檔案:#include <unistd.h>

函數原型:int getopt(int argc, char * const argv[], const char *optstring, const struct option *long_opts, int *longindex);

與 getopt_long() 的差別:

  • 該函數與 getopt_long() 函數使用相同的參數表,在功能上基本一緻
  • 隻是 getopt_long() 隻将 --name 當作長參數,但 getopt_long_only() 會将 --name 和 -name 兩種選項都當作長參數來比對
  • getopt_long() 在遇到 -name 時,會拆解成 -n -a -m -e 到 optstring 中進行比對,而 getopt_long_only() 隻在 -name 不能在longopts() 中比對時才将其拆解成 -n -a -m -e 這樣的參數到 optstring 中進行比對