getopt函數的使用——分析命令行參數

getopt(分析命令行參數)

  • 相關函數表頭文件
    #include<unistd.h>
  • 函數聲明
    int getopt(int argc,char * const argv[ ],const char * optstring);
  • 全局變量

    extern char *optarg;git

    extern int optind, opterr, optopt;  //索引/錯誤輸出標誌/最後一個未知選項數組

  • 函數說明
    getopt()用來分析命令行參數。參數argcargv是由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都是合法的。這裏須要注意三點:

一、不帶值的參數能夠連寫,象1a是不帶值的參數,它們能夠-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 }
getopt示例代碼

 

執行:

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 }
getopt_long示例代碼
相關文章
相關標籤/搜索