2015-02-05 61 views
1

我遇到了getopt問題。在我的程序中,我希望使用以下選項運行該程序:-l -w -n -bnb是可選的,但程序必須有lw,而不是兩者。另外,如果調用w,則必須緊跟一個參數。此外,訂單應該是lw第一,然後是nb,其順序無關緊要。getopt中的選項順序問題

以下是有效的論據例子:

./prog -l -n -b 
./prog -w argument -b -n 
./prog -l -n 
./prog -l -b 

這些例子是無效的:

./prog -l -w argument 
./prog -n -l 
./prog -b -l 

基於這些要求,我已經使用getopt的有問題。當然,我可以使用大量的if else語句,但這會很難看,也不必要的複雜。

具體而言,我遇到了參數的順序問題,並且使-l-w選項成爲一種關係。

這是我到目前爲止,雖然它不是很多,因爲這些不確定性。

while ((option = getopt(argc, argv,"lw:nb:")) != -1) { 
    switch(option) { 
    case'l': ... // I haven't wrote anything here yet 
    case'w': ... 
    case'n': ... 
    case'b': ... 
    case '?': ... 
    default: ... 
    } 
} 
+0

你能告訴我們你到目前爲止試過的嗎? – larsks 2015-02-05 22:12:02

+0

當然,我會發布我迄今爲止所擁有的。 – mrQWERTY 2015-02-05 22:12:32

+0

請注意這個問題[我可以使用'getopt()'按特定順序處理選項嗎?](http://stackoverflow.com/questions/26473642/can-i-use-getopt-to-process-options-in -a-certain-order),但答案只與下面的答案兼容 - 它沒有詳細說明,也不包含代碼段。 – 2015-02-05 23:41:06

回答

2

首先,getopt確保w有一個參數。這就是getopt字符串中的 :的一點。如果-b不需要參數,那麼您應該在它後面刪除:

其次,我不認爲驗證參數條件是一樣糟糕,因爲你想 它會。你應該已經有變量來保持你 選擇曲目,像這樣:

int opt_l = 0; 
int opt_w = 0; 
char *arg_w = 0; 
int opt_n = 0; 
int opt_b = 0; 

你也應該有打印出的使用和有用的錯誤 信息給用戶,這樣的功能:

int exit_usage(const char *err) 
{ 
    if(err) { printf("Bad arguments: %s\n", err); } 
    printf("Usage: ...\n"); 
    exit(1); 
} 

然後,這是一個簡單的單行檢查來驗證您的先決條件。如果 前提條件失敗,則打印一個錯誤並向用戶顯示使用情況信息。 您不必將前提條件檢查插入一行,但當趨向於 時,如果它們全部都是一行,則可以更容易地閱讀前提條件列表。 我喜歡這個:

while ((option = getopt(argc, argv, "lw:nb")) != -1) 
{ 
    switch(option) 
    { 
    case 'l': 
     if(opt_w != 0) { exit_usage("Cannot combine -l with -w"); } 
     ++opt_l; 
     break; 
    case 'w': 
     if(opt_l != 0) { exit_usage("Cannot combine -l with -w"); } 
     arg_w = optarg; 
     ++opt_w; 
     break; 
    case 'n': 
     if(opt_l == 0 && opt_w == 0) { exit_usage("-n requires -l or -w first"); } 
     ++opt_n; 
     break; 
    case 'b': 
     if(opt_l == 0 && opt_w == 0) { exit_usage("-n requires -l or -w first"); } 
     ++opt_b; 
     break; 
    case '?': 
     exit_usage(NULL); 
     break; 
    default: 
     break; 
    } 
} 
+1

非常好!我只會補充:_First審查您的要求。爲什麼'-l'或'-w arg'要先於'-b'或'-n'?如果'-b'首先出現什麼樣的災難呢?_合理的答案是「我在'b'中執行代碼:'並且如果'-l'和'-w arg'都不知道該怎麼辦指定」。在執行操作之前,請等到循環結束,或按照此答案中所示執行操作。 – 2015-02-05 23:31:32

+2

@JonathanLeffler:謝謝,我準備寫一段關於這個的文章,但完全忘了。我認爲這是一個紅旗,爭論有如此嚴格的順序。 – indiv 2015-02-05 23:32:58

+0

這太棒了!對於像我這樣的初學者來說,getopt()是一個很好的開始。在此之前,我正在寫一個有4個nest if語句的參數檢查器! – mrQWERTY 2015-02-06 03:07:51