1、Linux傳入引數處理
在介紹使用getopt函式處理應用程式傳入引數前,先來看一下Linux環境下撰寫的應用程式是如何處理傳入的引數的
Linux環境撰寫應用程式時,main函式一般會有兩個引數,用于描述執行應用程式時傳入的引數,書寫形式如下:
int main(int argc, char *argv[])
- argc:表示傳入引數的個數
- argv:指標陣列,每一項存放一個傳入引數字串的地址
在shell中啟動這個應用程式,shell接受用戶輸入命令列,將命令列分解成單詞,然后把這些單詞放入到一個陣列,作業系統將這個存放單詞陣列的長度和陣列作為引數傳遞給了main函式,因此,實際情況下,argv[0]指向的一定是運行當前應用程式的全路徑名稱,argv[1]~argv[argc-1]指向的才是傳入引數,實際傳入引數的個數為argc-1
例如有一個名為hello_world應用程式,在shell中按照 "./hello_world 3" 執行該程式,此時,argc = 2,argv[0]指向的是 "./hello_world" 字串存放地址,argv[1]指向的才是傳入引數 "3" 字串存放地址
顯然,我們可以在main函式內自己撰寫程式,通過決議argc,argv引數來獲取執行應用程式所傳入的引數,但對于Linux這種廣泛使用的作業系統,它已經在庫函式中為用戶提供了用于命令列引數決議的函式,我們直接呼叫這些函式,便可輕松的決議各種命令列引數模式
這里所講的getopt函式,就是標準庫中實作的一個用于決議命令列引數的函式,它支持需要關聯值和不需要關聯值的選項,而且簡單易用
(所謂的需要關聯值的選項,以gcc編譯器為例子,gcc的-o選項表示輸出可執行程式名稱,這個后面就需要跟一個名稱才能正常使用,后面一個引數就是-o命令的關聯值;所謂的不需要關聯值,以ls命令為例子, ls的-l命令表示列出當前目錄所有檔案,這個后面不需要跟一些其他資訊,這種被稱作不需要關聯值的選項)
2、getopt函式的原型
getopt函式有三個引數,函式的原型如下:
int getopt(int argc, char * const argv[], const char *optstring); extern char *optarg; extern int optind, opterr, optopt;
getopt函式本質上其實就是對main函式傳入的argc和argv引數進行處理,它將傳遞給程式的main函式的argc和argv作為引數,同時接受一個選項指定字串optstring,optstring字串告訴getopt哪些選項可用,以及它們是否有關聯值,
optstring是一個字串串列,每個字符代表一個單字符選項,如果一個字符后面緊跟一個冒號(:),則表示一個該選項有一個關聯值作為下一個引數,
例如:getopt(argc, argv, "if:l")
它允許-i、-f、-l作為引數,其中-f選項后要緊跟一個引數,也就是它的關聯值,這里引數的傳遞可以不按照optstring字串串列寫入的順序來傳
getopt的回傳值是argv陣列中的下一個選項字符,回圈呼叫getopt可以依次得到argv中每一個選項,函式的處理行為如下:
- 如果選項處理完畢,回傳值為-1,回圈遇到-1,引數判斷完畢,可以退出回圈
- 如果選項有一個關聯值,全域變數optarg指向這個值
- 如果遇到不在optstring中選項,getopt回傳一個問號(?),并將無法識別選項存放到全域變數optopt,有些getopt版本會在遇到未知選項時列印錯誤資訊
- 如果選項要求有關聯值,但是用戶沒傳入一個關聯值,默認情況下getopt通常回傳一個問號(?),我們可以將選項字串的第一個字符設定成冒號,這個沒傳入關聯值時,回傳的是冒號(:)而不是問號(?)
optind表示下一個待處理引數的索引,getopt利用它來記錄自己的進度,一般情況下在程式中很少用到
3、函式的使用
撰寫一個簡單的例子,來演示getopt函式使用
#include <stdio.h> #include <unistd.h> int main(int argc, char *argv[]) { int res; while((res = getopt(argc, argv, ":io:l")) != -1) { switch(res) { case 'i': case 'l': printf("option: %c\n", res); break; case 'o': printf("option: %c %s\n", res, optarg); break; case ':': printf("option need a value\n"); break; case '?': printf("unknown option: %c\n", optopt); break; default: break; } } }
演示程式中的main函式內使用getopt函式對傳入引數進行決議,支持引數有-i、-o、-l,其中-o引數后要有一個關聯值,這里optstring引數的第一個字符設定成冒號,是用來分辨輸入-o選項,但沒傳入關聯值情況,這種情況(:)被回傳
如果傳入-i、-l引數,列印引數資訊
如果傳入-o引數,列印引數資訊和關聯值資訊
如果傳入-o引數,并沒傳入關聯值,列印出提示資訊
如果傳入無效引數時,列印出不識別提示資訊
4、小結
呼叫getopt函式可以方便的處理我們程式中傳入的不同引數,它按照我們指定的方式來決議main函式中傳入的argc和argv引數,并回傳選項字符,支持的引數在getopt的optstring引數指定,通過引數后面冒號(:)的有無來表示該引數后面是否需要緊跟關聯值資訊,但getopt函式也有自己的局限性,它僅支持的是單字符引數,如果想接受比單字符選項含義更明確的引數時,就不適用了,不過,如果你有這種需求,可以去研究下C庫中getopt函式的另一個增強版本——getopt_long,它接受以下劃線(--)開始的長引數
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/249675.html
標籤:其他
