getopt()函數解析

在需要命令行解析時,肯尼個都想到的是自己寫,沒有意識到已經有getopt函數,下面就介紹getopt函數:
          #include <unistd.h>
        extern 
char *optarg; 
        extern 
int optind,   // 初始化值爲1,下一次調用getopt時,從optind存儲的位置重新開始檢查選項。 
        extern int opterr,   // 初始化值爲1,當opterr=0時,getopt不向stderr輸出錯誤信息。
        extern int optopt;  // 當命令行選項字符不包括在optstring中或者選項缺少必要的參數時,
                                    
// 該選項存儲在optopt中, getopt返回'?’。
        int getopt(int argc, char * const argv[], const char *optstring);
        optarg和optind是兩個最重要的external 變量。optarg是指向參數的指針(當然這隻針對有參數的選項);optind是argv[]數組的索引,衆所周知,argv[0]是函數名稱,所有參數從argv[1]開始,所以optind被初始化設置指1。每調用一次getopt()函數,返回一個選項,如果該選項有參數,則optarg指向該參數。 在命令行選項參數再也檢查不到optstring中包含的選項時,返回-1。
        函數getopt()有三個參數,argc和argv[]應該不需要多說,下面說一下字符串optstring,它是作爲選項的字符串的列表。
        函數getopt()認爲optstring中,以'-’開頭的字符(注意!不是字符串!!)就是命令行參數選項,有的參數選項後面可以跟參數值。optstring中的格式規範如下:
1) 單個字符,表示選項,
2) 單個字符後接一個冒號”:”,表示該選項後必須跟一個參數值。參數緊跟在選項後或者以空格隔開。該參數的指針賦給optarg。
3) 單個字符後跟兩個冒號”::”,表示該選項後必須跟一個參數。參數必須緊跟在選項後不能以空格隔開。該參數的指針賦給optarg。(這個特性是GNU的擴張)。
        例如optstring="ab:c::d::",程序名稱爲test.ext,在命令行下運行該程序:
        test.exe --b host -ckeke -d haha
        在這個命令行參數中,-a和-h就是選項元素,去掉'-',a,b,c就是選項。host是b的參數,keke是c的參數。但haha並不是d的參數,因爲它們中間有空格隔開。所以上面的命令行調用會出錯。
        默認情況下getopt會重新排列命令行參數的順序,所以到最後所有不包含選項的命令行參數都排到最後。例如:
        test.exe -a ima -b host -ckeke -d haha
        最後命令行參數的順序是: -a -b host -ckeke -d ima haha
        如果optstring中的字符串以'+'加號開頭或者環境變量POSIXLY_CORRE被設置。那麼一遇到不包含選項的命令行參數,getopt就會停止,返回-1。
    對getopt()函數的使用,通常用一個循環,不斷的調用它,獲得其參數選項以及參數值(如果有的話),直到取完最後一個命令行參數(getopt()函數返回值爲-1)。並且,爲了防止用戶不按照要求進行命令行輸入,會設計一個help選項,以告知用戶如何使用命令行運行該程序)。

對於以'--'開始的參數,應用getopt_long,需要知道兩個結構
1. 同getopt的字符串,表示短選項
2. 一個包含長選項字符串的結構數組,每個結構體包含四個域,第一個域爲長選項字符串,第二個域是一個標識,只能爲0、1和2,分別代表選項沒有參數、選項需要參數和選項參數是可選的。
第三個域如果指針爲NULL,則返回那麼getopt_long返回val字段的值,如果該指針不爲NULL,那麼會使得它所指向的結構填入val字段的值,同時getopt_long返回0
第四個域對應的是短選項的字符串。結構體數組的最後一個元素爲{NULL, 0, NULL, 0}
例子:
#include <stdio.h>
#include <getopt.h>
char *l_opt_arg;
char* const short_options = "nbl:";
struct option long_options[] = {
     { "name",     0,   NULL,    'n'     },
     { "bf_name",  0,   NULL,    'b'     },
     { "love",     1,   NULL,    'l'     },
     {      0,     0,     0,     0},
};
int main(int argc, char *argv[])
{
     int c;
     while((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1)
     {
         switch (c)
         {
         case 'n':
             printf("My name is XL./n");
             break;
         case 'b':
             printf("His name is ST./n");
             break;
         case 'l':
             l_opt_arg = optarg;
             printf("Our love is %s!/n", l_opt_arg);
             break;
         }
     }
     return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章