1. 程式人生 > >C++ 命令列引數解析

C++ 命令列引數解析

文章目錄

說明


主要參考以下部落格:

部落格一: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			# 長引數

錯誤的使用方法(×):

[[email protected]:~/Desktop]$ opt.exe -a -b -n -r required_para		# -b 沒有跟引數

注意事項:一般地,不要將短引數的 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 中進行匹配