在實際編程當中,本身編寫代碼處理命令行參數是比較麻煩且易出錯的。通常咱們會直接使用getopt()
和getopt_long()
函數,下文將介紹具體的使用方法。html
getopt()
用於處理」單字母「選項,如-a
, -t
等。函數聲明以下:web
#include <unistd.h> int getopt(int argc, char *const argv[], const char *optstring); extern char *optarg; extern int optind, opterr, optopt;
對於前兩個參數argc
和grgv[]
,通常直接使用main()
傳遞進來的數值。用過C語言的同窗應該比較熟悉,簡單複習一下。shell
#include <stdlib.h> #include <stdio.h> int main(int argc, char const *argv[]) { //在C99標準推出以前,變量不能在for()聲明,爲了兼容性,這裏提早聲明"i" int i; printf("argc = %d\n", argc); if (argc > 1) { for (i = 0; i < argc; ++i) { printf("argv[%d] = %s\n", i, argv[i]); } } return 0; }
argc
: argument count, 記錄了命令行參數的個數(包括命令自己)編程
argv
: argument vector, 記錄了命令行參數的具體內容數組
$ ./test 1 2 3 argc = 4 argv[0] = ./test argv[1] = 1 argv[2] = 2 argv[3] = 3
optstring
: 做爲getopt()
的第三個參數,用於規定合法選項(option)以及選項是否帶參數(argument)。通常爲合法選項字母構成的字符串,若是字母后面帶上冒號:
就說明該選項必須有參數。如"ht:"
說明有兩個選項-h
和-t
且後者(-t
)必須帶有參數(如-t 60
)。函數
option character
: 通常狀況下,getopt()
讀取到合法選項,就返回該選項(一個字母)。-1
:結束標誌。while ( (opt = getopt(argc, argv, "ab:") ) != -1) {...}
?
: 通常狀況下,遇到非法選項或者參數缺失都會返回?
。若是須要區分這兩種錯誤,能夠在optstring
的開頭加上:
,如:ht:
, 這樣參數缺失就返回:
,非法選項就返回?
。:
:在optstring
參數開頭第一個字符爲:
時,遇到參數缺失返回:
。參考下方代碼(摘自Linux Programming by Example)可幫助理解int oc; /* option character */ char *b_opt_arg; while ((oc = getopt(argc, argv, ":ab:")) != -1) { switch (oc) { case 'a': /* handle -a, set a flag, whatever */ break; case 'b': /* handle -b, get arg value from optarg */ b_opt_arg = optarg; break; case ':': /* missing option argument 參數缺失*/ fprintf(stderr, "%s: option '-%c' requires an argument\n", argv[0], optopt); break; case '?': default: /* invalid option 非法選項*/ fprintf(stderr, "%s: option '-%c' is invalid: ignored\n", argv[0], optopt); break; } }
optind
(option index): 數組下標,指向下一個未處理的參數。經過例子(摘自stackoverflow)能更好理解:#include <stdio.h> #include <string.h> #include <unistd.h> int main(int argc, char *argv[]) { char optStr[] = "ab"; int c; while ((c = getopt(argc, argv, optStr)) != -1) { printf("optind: %d\n", optind); switch (c) { case 'a': printf("-a\n"); break; case 'b': printf("-b\n"); break; case '?': printf("error\n"); break; } } return 0; }
測試結果:測試
$ ./a.out -ab #例子1 optind: 1 -a optind: 2 -b $ ./a.out -a #例子2 optind: 2 -a
例子1:ui
#argv[]數據以下 argv[0]="./a.out" argv[1]="-ab" argv[2]=0
從optind
=1開始,處理完a
,optind
指向b
所在位置,其實仍是1;處理完b,指向下一個選項,即2命令行
例子2:指針
#argv[]數據以下 argv[0]="./a.out" argv[1]="-a" argv[2]=0
從optind
=1開始,處理完a,指向下一個選項,即2
optarg
: 若是合法選項帶有參數,那麼對應的參數,賦值給optarg
根據函數名就能夠知道getopt_long()
用於處理長選項,如-help
。函數聲明以下:
#include <getopt.h> int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex);
前三個選項和getopt()
徹底相同,在此再也不贅述。
longopts數組
: 用於規定合法長選項以及長選項是否帶參數(argument)。涉及到的option結構體
聲明以下struct option { const char *name; int has_arg; int *flag; int val; };
name
: 長選項的名稱has_arg
: 參數狀況符號常量 | 數值 | Meaning |
---|---|---|
no_argument |
0 |
無參數 |
required_argument |
1 |
有參數 |
optional_argument |
2 |
參數可選 |
考慮到「可讀性」,通常使用「符號常量」
int *flag
: 若是flag
爲 NULL
, getup_long()
返回val
的值; 若是不是NULL
, val
的值賦給flag
指針指向的內容,同時getopt_long()
返回 0int val
: flag
爲NULL
,val
做爲getopt_long()
的返回值;若是flag
不爲NULL
,val
賦值給flag
指針所指內容;int *flag | return value |
---|---|
NULL |
val |
&name (<— val ) |
0 |
經過例子(摘自webbench)可加深理解
static const struct option long_options[]= { {"force",no_argument,&force,1}, //-force 參數三(flag)不爲NULL,force=1,getopt_long()返回0 {"reload",no_argument,&force_reload,1}, {"time",required_argument,NULL,'t'}, {"help",no_argument,NULL,'?'}, //-help 第三個參數(flag)爲NULL,直接返回 "?" {"http09",no_argument,NULL,'9'}, {"http10",no_argument,NULL,'1'}, {"http11",no_argument,NULL,'2'}, {"get",no_argument,&method,METHOD_GET}, {"head",no_argument,&method,METHOD_HEAD}, {"options",no_argument,&method,METHOD_OPTIONS}, {"trace",no_argument,&method,METHOD_TRACE}, {"version",no_argument,NULL,'V'}, {"proxy",required_argument,NULL,'p'}, {"clients",required_argument,NULL,'c'}, {NULL,0,NULL,0} //最後一個元素應該全爲0 }; int main(int argc, char *argv[]) { int options_index=0; ... while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF ) { ... } }
注意:
longopts數組
的最後一個元素應該全爲0.
longindex
: 通常設置爲NULL
; 若是不爲NUll
, 指向每次找到的長選項在longopts
的位置,能夠經過該值(即索引)找到當前長選項的具體信息。但願本文能幫助你們更好地理解getopt()
和getopt_long()
。
更多的相關用法能夠參考Linux Programming by Example: The Fundamentals