命令行參數解析函數getopt和getopt_long函數【轉】
原文地址:http://blog.csdn.net/cashey1991/article/details/7942809
getopt和getopt_long函數
平時在寫程序時常常需要對命令行參數進行處理,當命令行參數個數較多時,如果按照順序一個一個定義參數含義很容易造成混亂,而且如果程序只按順序處理參數的話,一些“可選參數”的功能將很難實現。在Linux中,我們可以使用getopt、getopt_long、getopt_long_only來對這個問題進行處理。
1 #include <unistd.h> 2 3 int getopt(int argc, char* const argv[], 4 const char *optstring); 5 6 extern char *optarg; 7 extern int optind, opterr, optopt; 8 9 #include <getopt.h> 10 11 int getopt_long(int argc, char * const argv[], 12 const char *optstring, 13 const struct option *longopts, int*longindex); 14 15 int getopt_long_only(int argc, char * const argv[], 16 const char *optstring, 17 const struct option *longopts, int *longindex);
從最簡單的getopt講起,getopt函數的前兩個參數,就是main函數的argc和argv,這兩者直接傳入即可,要考慮的就只剩下第三個參數。
optstring的格式舉例說明比較方便,例如:
char *optstring = "abcd:";
上面這個optstring在傳入之後,getopt函數將依次檢查命令行是否指定了 -a, -b, -c及 -d(這需要多次調用getopt函數,直到其返回-1),當檢查到上面某一個參數被指定時,函數會返回被指定的參數名稱(即該字母)
最後一個參數d後面帶有冒號,: 表示參數d是可以指定值的,如 -d 100 或 -d user。
optind表示的是下一個將被處理到的參數在argv中的下標值。
如果指定opterr = 0的話,在getopt、getopt_long、getopt_long_only遇到錯誤將不會輸出錯誤信息到標準輸出流。
1 #include <unistd.h> 2 #include <stdlib.h> 3 #include <stdio.h> 4 5 int main(int argc, char *argv[]) 6 { 7 int opt; 8 char *optstring = "a:b:c:d"; 9 10 while ((opt = getopt(argc, argv, optstring)) != -1) 11 { 12 printf("opt = %c\n", opt); 13 printf("optarg = %s\n", optarg); 14 printf("optind = %d\n", optind); 15 printf("argv[optind - 1] = %s\n\n", argv[optind - 1]); 16 } 17 18 return 0; 19 }
編譯上述程序並運行,有如下結果:
1 cashey@ubuntu:~/Desktop/getopt$ ./test_getopt -a 100 -b 200 -c admin -d 2 opt = a 3 optarg = 100 4 optind = 3 5 argv[optind - 1] = 100 6 7 opt = b 8 optarg = 200 9 optind = 5 10 argv[optind - 1] = 200 11 12 opt = c 13 optarg = admin 14 optind = 7 15 argv[optind - 1] = admin 16 17 opt = d 18 optarg = (null) 19 optind = 8 20 argv[optind - 1] = -d
下面來講getopt_long函數,getopt_long函數包含了getopt函數的功能,並且還可以指定“長參數”(或者說長選項),與getopt函數對比,getopt_long比其多了兩個參數:
1 int getopt(int argc, char * const argv[], 2 const char *optstring); 3 4 int getopt_long(int argc, char * const argv[], 5 const char *optstring, 6 const struct option *longopts, int *longindex);
在這裏,longopts指向的是一個由option結構體組成的數組,那個數組的每個元素,指明了一個“長參數”(即形如--name的參數)名稱和性質:
struct option { const char *name; int has_arg; int *flag; int val; };
name 是參數的名稱
has_arg 指明是否帶參數值,其數值可選:
1 no_argument (即 0) 表明這個長參數不帶參數(即不帶數值,如:--name) 2 required_argument (即 1) 表明這個長參數必須帶參數(即必須帶數值,如:--name Bob) 3 optional_argument(即2)表明這個長參數後面帶的參數是可選的,(即--name和--name Bob均可)
flag 當這個指針為空的時候,函數直接將val的數值從getopt_long的返回值返回出去,當它非空時,val的值會被賦到flag指向的整型數中,而函數返回值為0
val 用於指定函數找到該選項時的返回值,或者當flag非空時指定flag指向的數據的值。
另一個參數longindex,如果longindex非空,它指向的變量將記錄當前找到參數符合longopts裏的第幾個元素的描述,即是longopts的下標值。
1 #include <unistd.h> 2 #include <stdlib.h> 3 #include <stdio.h> 4 #include <getopt.h> 5 6 int 7 main(int argc, char **argv) 8 { 9 int opt; 10 int digit_optind = 0; 11 int option_index = 0; 12 char *optstring = "a:b:c:d"; 13 static struct option long_options[] = { 14 {"reqarg", required_argument, NULL, ‘r‘}, 15 {"noarg", no_argument, NULL, ‘n‘}, 16 {"optarg", optional_argument, NULL, ‘o‘}, 17 {0, 0, 0, 0} 18 }; 19 20 while ( (opt = getopt_long(argc, argv, optstring, long_options, &option_index)) != -1) 21 { 22 printf("opt = %c\n", opt); 23 printf("optarg = %s\n", optarg); 24 printf("optind = %d\n", optind); 25 printf("argv[optind - 1] = %s\n", argv[optind - 1]); 26 printf("option_index = %d\n", option_index); 27 } 28 29 return 0; 30 }
編譯運行以上程序並運行,可以得到以下結果:
1 cashey@ubuntu:~/Desktop/getopt$ ./test_getopt_long -a 100 --reqarg 100 --nonarg 2 opt = a 3 optarg = 100 4 optind = 3 5 argv[optind - 1] = 100 6 option_index = 0 7 opt = r 8 optarg = 100 9 optind = 5 10 argv[optind - 1] = 100 11 option_index = 0 12 ./test_getopt_long: unrecognized option ‘--nonarg‘ 13 opt = ? 14 optarg = (null) 15 optind = 6 16 argv[optind - 1] = --nonarg 17 option_index = 0
當所給的參數存在問題時,opt(即函數返回值是‘?‘),如:
1 cashey@ubuntu:~/Desktop/getopt$ ./test_getopt_long -a 2 ./test_getopt_long: option requires an argument -- ‘a‘ 3 opt = ? 4 optarg = (null) 5 optind = 2 6 argv[optind - 1] = -a 7 option_index = 0 8 cashey@ubuntu:~/Desktop/getopt$ ./test_getopt_long --reqarg 9 ./test_getopt_long: option ‘--reqarg‘ requires an argument 10 opt = ? 11 optarg = (null) 12 optind = 2 13 argv[optind - 1] = --reqarg
最後說說getopt_long_only函數,它與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中進行匹配。
命令行參數解析函數getopt和getopt_long函數【轉】