#include<unistd.h>
int getopt(int argc,char * const argv[ ],const char * optstring);
extern char *optarg;git
extern int optind, opterr, optopt; //索引/錯誤輸出標誌/最後一個未知選項數組
getopt()
用來分析命令行
參數。參數argc
和argv
是由main()
傳遞的參數個數
和內容
。參數optstring
則表明欲處理的選項字符串
。此函數會返回在argv
中下一個的選項字母
,此字母會對應參數optstring
中的字母。若是選項字符串裏的字母后接着冒號「:」
,則表示還有相關的參數,全域變量optarg
即會指向此額外參數。若是getopt()
找不到符合的參數,則會打印出錯信息,並將全域變量optarg
設爲「?」
字符,若是不但願getopt()
打印出錯信息,則只要將全域變量opterr
設爲0
便可。getopt() 所設置的全局變量包括:bash
char *optarg
——當前選項參數字串(若是有)。 app
int optind
——argv的當前索引值。當getopt()在while循環中使用時,循環結束後,剩下的字串視爲操做數,在argv[optind]至argv[argc-1]中能夠找到。 ide
int opterr——這個變量非零時,getopt()函數爲「無效選項」和「缺乏參數選項,並輸出其錯誤信息。
函數
int optopt
——當發現無效選項字符之時,getopt()函數或返回'?'字符,或返回':'字符,而且optopt包含了所發現的無效選項字符。ui
getopt()
使用optstring
所指的字串做爲短參數列表,象"1ac:d::"
就是一個短參數列表。短參數的定義是一個-
後面跟一個字母或數字
,象-a
,-b
就是一個短參數
。每一個數字或字母定義一個參數。 this
其中短參數在getopt定義裏分爲三種:spa
一、不帶值的參數,它的定義便是參數自己。命令行
二、必須帶值的參數,它的定義是在參數自己後面再加一個冒號。
三、可選值的參數,它的定義是在參數自己後面加兩個冒號 。
在這裏拿上面的"1ac:d::"
做爲樣例進行說明,其中的1
,a
就是不帶值
的參數,c
是必須帶值
的參數,d
是可選值
的參數。
在實際調用中,-1 -a -c cvalue -d
, -1 -a -c cvalue -ddvalue
,-1a -ddvalue -c cvalue
都是合法的。這裏須要注意三點:
一、不帶值
的參數能夠連寫
,象1
和a
是不帶值的參數,它們能夠-1 -a
分開寫,也能夠-1a
或-a1
連寫。
二、參數不分前後順序,-1a -c cvalue -ddvalue
和-d -c cvalue -a1
的解析結果是同樣的。
三、要注意可選值
的參數的值
與參數
之間不能有空格
,必須寫成-ddvalue
這樣的格式,若是寫成-d dvalue
這樣的格式就會解析錯誤。
默認狀況下getopt會從新排列命令行參數的順序,因此到最後全部不包含選項的命令行參數都排到最後。
getopt()每次調用會逐次返回命令行傳入的參數。
當沒有參數
的最後的一次調用時,getopt()將返回-1
。
當解析到一個不在optstring
裏面的參數,或者一個必選值參數不帶值
時,返回?
。
當optstring是以:
開頭時,缺值參數
的狀況下會返回:
,而不是?
。
1 #include <unistd.h> 2 #include <stdlib.h> 3 #include <stdio.h> 4 5 int 6 main(int argc, char *argv[]) 7 { 8 int opt; /*接收選項*/ 9 extern char* optarg;/*指向當前getopt()返回選項的參數*/ 10 extern int optopt; /*當選項沒有出如今optstring中,或者選項缺乏必要的參數時,該選項存儲在optopt中,getopt返回'?’*/ 11 extern int opterr; /*用於控制getopt()是否打印出錯信息*/ 12 extern int optind; /*當前getopt()返回選項的下一個選項的索引(argv數組)*/ 13 14 opterr = 0; /*不要打印出錯信息*/ 15 16 while ((opt = getopt(argc, argv, "a1b:c::")) != -1) { 17 /* a和1爲不帶參數選項,b爲必須帶一個參數選項,c爲可選參數選項(注意參數與-c直接不能分開) */ 18 /* 示例: getopt -a -b 100 -c12 */ 19 switch (opt) { 20 case 'a': 21 case '1': 22 printf("選項: %c\n",opt); 23 break; 24 case 'b': 25 printf("選項: b,帶的參數是 %s\n",optarg); 26 break; 27 case 'c': 28 printf("選項: c,帶的參數是 %s\n",optarg); 29 break; 30 default: /* '?' */ 31 if(optopt == 'c'){ 32 printf("選項: c,沒有帶參數\n"); 33 break; 34 } 35 fprintf(stderr, "用法: %s [-1a] [-c [argument]] [-b argument]\n", 36 argv[0]); 37 exit(EXIT_FAILURE); //無效的參數,退出程序 38 } 39 } 40 printf("optind=%d\n",optind); 41 42 //在命令行選項參數再也檢查不到optstring中包含的選項時, 43 //返回-1,同時optind儲存第一個不包含選項的命令行參數。 44 //getopt 中指的 選項是指以 `-`開頭的 45 if (optind >= argc) { 46 fprintf(stderr, "選項索引超過了argv數組的長度\n"); 47 exit(EXIT_FAILURE); 48 } 49 //輸出第一個不包含選項的參數 50 printf("非選項參數 = %s\n", argv[optind]); 51 52 //輸出一下命令行參數,看看是否被改變 53 for(opt = 0; opt < argc ; ++opt){ 54 printf("索引:%d\t\t命令行參數:%s\n",opt,argv[opt]); 55 } 56 57 exit(EXIT_SUCCESS); //成功退出 58 }
fx@fx:~/code$ ./getopt -a -b 100 -c12 選項: a 選項: b,帶的參數是 100 選項: c,帶的參數是 12 optind=5 選項索引超過了argv數組的長度 fx@fx:~/code$ ./getopt -a 哈哈 -b 100 -c12 選項: a 選項: b,帶的參數是 100 選項: c,帶的參數是 12 optind=5 非選項參數 = 哈哈 索引:0 命令行參數:./getopt 索引:1 命令行參數:-a 索引:2 命令行參數:-b 索引:3 命令行參數:100 索引:4 命令行參數:-c12 索引:5 命令行參數:哈哈
getopt_long示例代碼
1 #include <unistd.h> 2 #include <stdlib.h> 3 #include <stdio.h> 4 5 extern int optind, opterr, optopt; 6 7 int 8 main(int argc, char **argv) 9 { 10 int c; /* 用於接收字符選項 */ 11 int digit_optind = 0; /* 用於接收數字選項 */ 12 13 while (1) { 14 /* */ 15 int this_option_optind = optind ? optind : 1; 16 int option_index = 0; 17 /* 長選項結構體數組 */ 18 static struct option long_options[] = { 19 {"add", required_argument, 0, 0 }, //須要一個參數 20 {"append", no_argument, 0, 0 }, //沒有參數 21 {"delete", required_argument, 0, 0 }, 22 {"verbose", no_argument, 0, 0 }, 23 {"create", required_argument, 0, 'c'}, //返回字符'c' 24 {"file", required_argument, 0, 0 }, 25 {0, 0, 0, 0 } 26 }; 27 /* 28 struct option { 29 const char *name; //選項名稱 30 int has_arg; //參數標誌(no_argument/0沒有參數;required_argument/1須要一個參數;optional_argument/2一個可選參數) 31 int *flag; //指定如何返回一個較長的選項。當這個指針爲空的時候,函數直接將val的數值從getopt_long的返回值返回出去,當它非空時,val的值會被賦到flag指向的整型數中,而函數返回值爲0 32 int val; //用於指定函數找到該選項時的返回值,或者當flag非空時指定flag指向的數據的值。 33 }; 34 */ 35 /* 獲取一個選項 */ 36 c = getopt_long(argc, argv, "abc:d:012", 37 long_options, &option_index); 38 39 if (c == -1){ /* 無參數可獲取了 */ 40 break; 41 } 42 43 switch (c) { /* 獲取參數解析 */ 44 case 0: 45 printf("選項是:%s", long_options[option_index].name); 46 if (optarg){ /*若是是帶參數的選項 */ 47 printf(" 參數是: %s", optarg); 48 } 49 printf("\n"); 50 break; 51 52 case '0': 53 case '1': 54 case '2': 55 if (digit_optind != 0 && digit_optind != this_option_optind) 56 printf("digits occur in two different argv-elements.\n"); 57 digit_optind = this_option_optind; 58 printf("選項: %c\n", c); 59 break; 60 61 case 'a': 62 printf("選項: a\n"); 63 break; 64 65 case 'b': 66 printf("選項: b\n"); 67 break; 68 case 'c': 69 printf("選項: c 帶的值: '%s'\n", optarg); 70 break; 71 72 case 'd': 73 printf("選項: d 帶的值: '%s'\n", optarg); 74 break; 75 76 case '?': 77 break; 78 79 default: 80 printf("?? getopt 返回字符代碼 0%o ??\n", c); 81 } 82 } 83 84 if (optind < argc) { 85 printf("非選項的命令行參數項: "); 86 while (optind < argc) 87 printf("%s ", argv[optind++]); 88 printf("\n"); 89 } 90 exit(EXIT_SUCCESS); 91 }