linux之getopt 函式(轉)

weixin_34119545發表於2017-08-18

命令列引數解析函式 —— getopt()

getopt()函式宣告如下:
1 #include <unistd.h>
2 
3 int getopt(int argc, char * const argv[], const char *optstring);
4 
5 extern char *optarg;
6 extern int optind, opterr, optopt;
該函式的argc和argv引數通常直接從main()的引數直接傳遞而來。optstring是選項字母組成的字串。如果該字串裡的任一字元後面有冒號,那麼這個選項就要求有選項引數。
當給定getopt()命令引數的數量 (argc)、指向這些引數的陣列 (argv) 和選項字串 (optstring) 後,getopt() 將返回第一個選項,並設定一些全域性變數。使用相同的引數再次呼叫該函式時,它將返回下一個選項,並設定相應的全域性變數。如果不再有可識別的選項,將返回 -1,此任務就完成了。
getopt() 所設定的全域性變數包括:
  • char *optarg——當前選項引數字串(如果有)。
  • int optind——argv的當前索引值。當getopt()在while迴圈中使用時,迴圈結束後,剩下的字串視為運算元,在argv[optind]至argv[argc-1]中可以找到。
  • int opterr——這個變數非零時,getopt()函式為“無效選項”和“缺少引數選項,並輸出其錯誤資訊。
  • int optopt——當發現無效選項字元之時,getopt()函式或返回'?'字元,或返回':'字元,並且optopt包含了所發現的無效選項字元。
以下面的程式為例:
選項:
  • -n —— 顯示“我的名字”。
  • -g —— 顯示“我女朋友的名字”。
  • -l —— 帶引數的選項.

清單2:

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 
 4 int main (int argc, char **argv)
 5 {
 6     int oc;                     /*選項字元 */
 7     char *b_opt_arg;            /*選項引數字串 */
 8 
 9     while((oc = getopt(argc, argv, "ngl:")) != -1)
10     {
11         switch(oc)
12         {
13             case 'n':
14                 printf("My name is Lyong.\n");
15                 break;
16             case 'g':
17                 printf("Her name is Xxiong.\n");
18                 break;
19             case 'l':
20                 b_opt_arg = optarg;
21                 printf("Our love is %s\n", optarg);
22                 break;
23         }
24     }
25    return 0;
26 }

執行結果:

 1 $ ./opt_parse_demo -n
 2 My name is Lyong.
 3 $ ./opt_parse_demo -g
 4 Her name is Xxiong.
 5 $ ./opt_parse_demo -l forever
 6 Our love is forever
 7 $ ./opt_parse_demo -ngl forever
 8 My name is Lyong.
 9 Her name is Xxiong.
10 Our love is forever

6、改變getopt()對錯誤命令列引數資訊的輸出行為

不正確的呼叫程式在所難免,這種錯誤要麼是命令列選項無效,要麼是缺少選項引數。正常情況下,getopt()會為這兩種情況輸出自己的出錯資訊,並且返回'?'。為了驗證此事,可以修改一下上面的清單2中的程式碼。

清單3:

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 
 4 int main (int argc, char **argv)
 5 {
 6     int oc;                     /*選項字元 */
 7     char *b_opt_arg;            /*選項引數字串 */
 8 
 9     while((oc = getopt(argc, argv, "ngl:")) != -1)
10     {
11         switch(oc)
12         {
13             case 'n':
14                 printf("My name is Lyong.\n");
15                 break;
16              case 'g':
17                 printf("Her name is Xxiong.\n");
18                 break;
19             case 'l':
20                 b_opt_arg = optarg;
21                 printf("Our love is %s\n", optarg);
22                 break;
23             case '?':
24                 printf("arguments error!\n");
25                 break;
26         }
27     }
28     return 0;
29 }

輸入一個錯誤的命令列,結果如下:

1 $ ./opt_parse_demo -l
2 ./opt_parse_demo: option requires an argument -- l
3 arguments error!
如果不希望輸出任何錯誤資訊,或更希望輸出自定義的錯誤資訊。可以採用以下兩種方法來更改getopt()函式的出錯資訊輸出行為:
  1. 在呼叫getopt()之前,將opterr設定為0,這樣就可以在getopt()函式發現錯誤的時候強制它不輸出任何訊息。
  2. 如果optstring引數的第一個字元是冒號,那麼getopt()函式就會保持沉默,並根據錯誤情況返回不同字元,如下:
    • “無效選項” —— getopt()返回'?',並且optopt包含了無效選項字元(這是正常的行為)。
    • “缺少選項引數” —— getopt()返回':',如果optstring的第一個字元不是冒號,那麼getopt()返回'?',這會使得這種情況不能與無效選項的情況區分開。

清單4:

 1 #include <stdio.h>
 2 #include <unistd.h>
 3 
 4 int main (int argc, char **argv)
 5 {
 6     int oc;                     /*選項字元 */
 7     char ec;                             /*無效的選項字元*/
 8     char *b_opt_arg;            /*選項引數字串 */
 9 
10     while((oc = getopt(argc, argv, ":ngl:")) != -1)
11     {
12         switch(oc)
13         {
14             case 'n':
15                 printf("My name is Lyong.\n");
16                 break;
17              case 'g':
18                 printf("Her name is Xxiong.\n");
19                 break;
20             case 'l':
21                 b_opt_arg = optarg;
22                 printf("Our love is %s\n", optarg);
23                 break;
24             case '?':
25                 ec = (char)optopt;
26                 printf("無效的選項字元 \' %c \'!\n", ec);
27                 break;
28             case ':':
29                 printf("缺少選項引數!\n");
30                 break;
31         }
32     }
33     return 0;
34 }
測試結果:

$ ./opt_parse_demo -a
無效的選項字元 ' a '!
$ ./opt_parse_demo -l
缺少選項引數!

 

轉自:http://blog.csdn.net/mr_jj_lian/article/details/6835137

相關文章