2013-10-26 94 views
3

我有一個程序,你在這裏輸入一個選項 -d 然後你是否在選項後面提供了一個非可選參數,做點什麼。
繼承人我的代碼:Getopt可選參數?

#include <stdio.h> 
#include <getopt.h> 
#include <stdlib.h> 

#define OPT_LIST "d::" 

int main (int argc, char *argv[]) 
{ 
    int c; 
    char string[] = "blah"; 

    while ((c = getopt (argc, argv, OPT_LIST)) != -1) 
    { 
     switch (c) 
     { 
      case 'd': 
        printf("%s\n", optarg); 
        break; 

      case '?': 
       fprintf(stderr, "invalid option\n"); 
       exit(EXIT_FAILURE); 
     } 
    } 
} 

所以,如果你選擇後進入一個非可選參數,它打印的說法。但如果用戶不提供非可選參數(這就是爲什麼我把雙冒號放在 OPT_LIST中),我希望它打印出字符串「字符串」。但我不知道如何做到這一點,所以任何幫助將不勝感激。

user:desktop shaun$ ./arg -d hello 
hello 
user:desktop shaun$ ./arg -d 
./arg: option requires an argument -- d 
invalid option 

我用C語言編寫運行在Mac的OS X:

繼承人當我運行該程序會發生什麼。

+0

嗯,'的printf( 「%S \ n」,字符串)'? – 2013-10-26 08:23:46

+0

我想它來打印字符串時,我喜歡運行的程序: ./arg -d – pudumaster

+0

這正是該行,如果在地方插入其中'fprintf中(錯誤,「無效選項\ n」),上面會做什麼;目前'駐留。 – 2013-10-26 08:34:32

回答

11

的「的選項可選值」功能僅僅是一個GNU libc的延伸,而不是由POSIX要求,並可能簡單地通過附帶的Mac OS X的libc中沒有實現

的選項參數是一個字符串,用於指定對該程序有效的選項字符。此字符串中的選項字符可以後跟一個冒號(':')以表示它接受了必需的參數。如果選項字符後跟兩個冒號('::'),則其參數是可選的;這是一個GNU擴展。

https://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html

事實上,POSIX.1-2008,第12.2節, 「實用語法指南」,明確禁止這項功能:

準則7:選項參數不宜選用。

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02

8

按照getopt文件,它將返回:如果與參數的選項沒有一個。它也設置optopt與匹配的參數。

因此,使用方法:

int main (int argc, char *argv[]) 
{ 
    int c; 
    while ((c = getopt (argc, argv, "d:f:")) != -1) 
    { 
     switch (c) 
     { 
      case 'd': 
      case 'f': 
       printf("option -%c with argument '%s'\n", c, optarg); 
       break; 
      case ':': 
       switch (optopt) 
       { 
       case 'd': 
        printf("option -%c with default argument value\n", optopt); 
        break; 
       default: 
        fprintf(stderr, "option -%c is missing a required argument\n", optopt); 
        return EXIT_FAILURE; 
       } 
       break; 
      case '?': 
       fprintf(stderr, "invalid option: -%c\n", optopt); 
       return EXIT_FAILURE; 
     } 
    } 
    return EXIT_SUCCESS; 
} 
+1

您需要使用'optstring = 「:d:F:」',最初的':',允許可選參數。一些非常討厭的是,雖然'富-d'和'如預期,'富-d -f arg'錯誤'-f'爲OPTARG爲'-d' ....任何整齊富-f arg'工作workwaround? – phs

+2

@phs,我想你必須手動檢查是否'optarg'看起來像一個選項(例如'OPTARG [0] == ' - ''),如果是這樣再倒回OPTIND讀它('optind- = 1; ')。如果你想接受(負數作爲一個可選的阿根廷,這可能在爲什麼POSIX [乾脆禁止他們]暗示http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap12.html#tag_12_02這是由棘手)(準則#7)。比照http://stackoverflow.com/a/32575314/2975337 – jrodatus

2

也許我誤解的問題。我正在閱讀它,就好像用戶想要超越getopt的默認錯誤處理一樣。如果是這樣的話,在OPT_LIST的開頭不應該有:我認爲上面的代碼是好的,但是,我認爲它仍然會打印

./arg: option requires an argument -- d 

要surpress的是,難道我們不需要一個:在OPT_LIST的開始?例如,改變這一點:

while ((c = getopt (argc, argv, "d:f:")) != -1) 

這樣:

while ((c = getopt (argc, argv, ":d:f:")) != -1) 

糾正我,如果我錯了。

0

試試這個解決方案。這個對我有用。考慮選項'z'作爲可選參數的選項。

int c; 
opterr = 0; //if (opterr != 0) (which it is by default), getopt() prints its own error messages for invalid options and for missing option arguments. 
while ((c = getopt (argc, argv, "x:y:z:")) != -1) 
    switch (c) 
    { 
     case 'x': 
     case 'y': 
     case 'z': 
      printf("OK ... option -%c with argument '%s'\n", c, optarg); 
      break; 

     case '?': 
      if (optopt == 'x' || optopt == 'y') 
       fprintf (stderr, "ERR ... Option -%c requires an argument.\n", optopt); 
      else if(optopt == 'z' && isprint(optopt)) 
      { 
       printf("OK ... option '-z' without argument \n"); 
       break; 
      } 
      else if (isprint (optopt)) 
       fprintf (stderr, "ERR ... Unknown option `-%c'.\n", optopt); 
      else 
       fprintf (stderr, "ERR ... Unknown option character `\\x%x'.\n", optopt); 
      return -1; 
     default: ; 
    } 

下面是一些例子:

./prog -x 
    ERR ... Option -x requires an argument. 

./prog -y 
    ERR ... Option -x requires an argument. 

./prog -z 
    OK ... option '-z' without argument 

./prog -x aaa 
    OK ... option -x with argument 'aaa' 

./prog -y bbb -x aaa 
    OK ... option -y with argument 'bbb' 
    OK ... option -x with argument 'aaa' 

./prog -x aaa -y bbb -z 
    OK ... option -x with argument 'aaa' 
    OK ... option -y with argument 'bbb' 
    OK ... option '-z' without argument 

./prog -x aaa -y bbb -z ccc 
    OK ... option -x with argument 'aaa' 
    OK ... option -y with argument 'bbb' 
    OK ... option -z with argument 'ccc'