GNU提供的getopt 函式的特點

2021-04-14 06:05:00 字數 4049 閱讀 1256

gnu提供的getopt()函式的特點

上面所設計的getopt()函式是unix支援小組提供的,其執行時一碰到不以'-'開始的 命令列引數就停止尋找選項。而gnu提供的getopt()函式與之不同,它會掃瞄整個命令列來尋找選項。當呼叫gnu getopt()函式並處理命令列引數的時候,它重新排列argv中的元素,這樣當重排結束時,所有選項都被移動到前面並且那些繼續檢查argv [optind]至argv[argc-1]中剩餘引數的**仍正常工作,但在任何情況下,碰到特殊引數'--'就結束對選項的掃瞄。

可以輸入乙個亂序的命令列,檢視opt_parse_demo的輸出:

$ ./opt_parse_demo -l forever a b c d -g -n

our love is forever

her name is xxiong.

my name is lyong.

gnu getopt()第二個特點是可以在optstring中使用特殊的首字元改變getopt()的預設行為:

gnu getopt()第三個特點是optstring中的選項字元後面接兩個冒號,就允許該選項有可選的選項引數。在選項引數不存在的情況下,gnu getopt()返回選項字元並將optarg設定為null。

20 世紀 90 年代,unix 應用程式開始支援長選項,即一對短橫線、乙個描述性選項名稱,還可以包含乙個使用等號連線到選項的引數。

gnu提供了getopt-long()和getopt-long-only()函式支援長選項的命令列解析,其中,後者的長選項字串是以乙個短橫線開始的,而非一對短橫線。

getopt_long()是同時支援長選項和短選項的getopt()版本。下面是它們的宣告:

#include

int getopt_long(int argc, char * const argv, const char *optstring, const struct option *longopts, int *longindex);

int getopt_long_only(int argc, char * const argv,const char *optstring,const struct option *longopts, int *longindex);

getopt_long ()的前三個引數與上面的getopt()相同,第4個引數是指向option結構的陣列,option結構被稱為「長選項表」。longindex引數 如果沒有設定為null,那麼它就指向乙個變數,這個變數會被賦值為尋找到的長選項在longopts中的索引值,這可以用於錯誤診斷。

option結構在getopt.h中的宣告如下:

struct option;

對結構中的各元素解釋如下:

這是選項名,前面沒有短橫線。譬如"help"、"verbose"之類。

描述了選項是否有選項引數。如果有,是哪種型別的引數,此時,它的值一定是下表中的乙個。

符號常量

數值含義

no_argument

0選項沒有引數

required_argument

1選項需要引數

optional_argument

2選項引數可選

如果這個指標為null,那麼 getopt_long()返回該結構val欄位中的數值。如果該指標不為null,getopt_long()會使得它所指向的變數中填入val欄位中 的數值,並且getopt_long()返回0。如果flag不是null,但未發現長選項,那麼它所指向的變數的數值不變。

這個值是發現了長選項時的返回值,或者flag不 是null時載入*flag中的值。典型情況下,若flag不是null,那麼val是個真/假值,譬如1或0;另一方面,如果flag是null,那麼 val通常是字元常量,若長選項與短選項一致,那麼該字元常量應該與optstring中出現的這個選項的引數相同。

每個長選項在長選項表中都有乙個單獨條目,該條目裡需要填入正確的數值。陣列中最後的元素的值應該全是0。陣列不需要排序,getopt_long()會進行線性搜尋。但是,根據長名字來排序會使程式設計師讀起來更容易。

以上所說的flag和val的用法看上去有點混亂,但它們很有實用價值,因此有必要搞透徹了。

大部分時候,程式設計師會根據getopt_long()發現的選項,在選項處理過程中要設定一些標記變數,譬如在使用getopt()時,經常做出如下的程式格式:

int do_name, do_gf_name, do_love; /*標記變數*/

char *b_opt_arg;

while((c = getopt(argc, argv, ":ngl:")) != -1)}

當flag不為null時,getopt_long*()會為你設定標記變數。也就是說上面的**中,關於選項'n'、'l'的處理,只是設定一些 標記,如果flag不為null,時,getopt_long()可以自動為各選項所對應的標記變數設定標記,這樣就能夠將上面的switch語句中的兩 種種情況減少到了一種。下面給出乙個長選項表以及相應處理**的例子。

#include

#include

int do_name, do_gf_name;

char *l_opt_arg;

struct option longopts = ,,,

,};int main(int argc, char *argv)

}return 0;}

在進行測試之前,再來回顧一下有關option結構中的指標flag的說明吧。

如果這個指標為null,那麼 getopt_long()返回該結構val欄位中的數值。如果該指標不為null,getopt_long()會使得它所指向的變數中填入val欄位中 的數值,並且getopt_long()返回0。如果flag不是null,但未發現長選項,那麼它所指向的變數的數值不變。

下面測試一下:

$ ./long_opt_demo --name

getopt_long()設定變數 : do_name = 1

getopt_long()設定變數 : do_gf_name = 0

$ ./long_opt_demo --gf_name

getopt_long()設定變數 : do_name = 0

getopt_long()設定變數 : do_gf_name = 1

$ ./long_opt_demo --love forever

our love is forever!

$ ./long_opt_demo -l forever

our love is forever!

測試過後,應該有所感觸了。關於flag和val的討論到此為止。下面總結一下get_long()的各種返回值的含義:

返回值   

含 義0     

getopt_long()設定乙個標誌,它的值與option結構中的val欄位的值一樣

1每碰到乙個命令列引數,optarg都會記錄它

'?'無效選項

':'缺少選項引數

'x'選項字元'x'

-1選項解析結束

從實用的角度來說,我們更期望每個長選項都對應乙個短選項,這種情況下,在option結構中,只要將flag設定為null,並將val設定為長選項所對應的短選項字元即可。譬如上面清單5中的程式,修改如下。

#include

#include

int do_name, do_gf_name;

char *l_opt_arg;

struct option longopts = ,,,

,};int main(int argc, char *argv)

}return 0;}

測試結果如下:

$ ./long_opt_demo --name --gf_name --love forever

my name is lyr.

her name is bx.

our love is forever!

$ ./long_opt_demo -ng -l forever

my name is lyr.

her name is bx.

our love is forever!

getopt 函式的使用

每一天你都在使用大量的命令列程式,是不是感覺那些命令列引數用起來比較方便,他們都是使用getopt來實現的。在linux下使用getopt寫程式是一種比較方便的事情,下面來簡單的介紹一下getopt的使用。在討論引數處理之前,我們先明確兩個概念 選項 選項引數 gcc g o test test.c...

getopt 函式的用法

另外apue的p619有解釋!通常 linux 下的各種命令都有許多的命令列引數可以選擇,比如 gcc g lm foo.c o foo getopt 就是用來分析命令列引數的函式。在繼續討論getopt 之前,先要明確兩個概念 選項 option 和 選項引數 argument 在上面的例子中,g...

函式getopt的用法

函式getopt 用來分析命令列引數,其函式原型和相關變數宣告如下 int getopt int argc,char const argv,const char optstring extern char optarg extern int optind,初始化值為1,下一次呼叫getopt時,從o...