2012-01-10 182 views
4
#include <iostream> 
#include <getopt.h> 

#define no_argument 0 
#define required_argument 1 
#define optional_argument 2 


int main(int argc, char * argv[]) 
{ 
    std::cout << "Hello" << std::endl; 

    const struct option longopts[] = 
    { 
    {"version", no_argument,  0, 'v'}, 
    {"help",  no_argument,  0, 'h'}, 
    {"stuff",  required_argument, 0, 's'}, 
    {0,0,0,0}, 
    }; 

    int index; 
    int iarg=0; 

    //turn off getopt error message 
    opterr=1; 

    while(iarg != -1) 
    { 
    iarg = getopt_long(argc, argv, "s:vh", longopts, &index); 

    switch (iarg) 
    { 
     case 'h': 
     std::cout << "You hit help" << std::endl; 
     break; 

     case 'v': 
     std::cout << "You hit version" << std::endl; 
     break; 

     case 's': 
     std::cout << "You hit stuff" << std::endl; 

     if(optarg) 
      std::cout << "Your argument(s): " << optarg << std::endl; 

     break; 
    } 
    } 

    std::cout << "GoodBye!" << std::endl; 

    return 0; 
} 

希望的輸出:如何使用getopt_long解析多個參數?

./a.out --stuff someArg1 someArg2 

Hello 
You hit stuff 
Your agument(s): someArg1 someArg2 
GoodBye! 
+0

實際輸出是多少? – Antti 2012-01-10 19:50:15

+0

它只捕捉1個參數:實際輸出你好 你碰到東西 你的參數:someArg1 GoodBye! – stackoverflow 2012-01-10 19:51:06

回答

7

getopt的返回-1,當所有選項 ARGS已被處理。 --stuff被認爲是一個參數,在這種情況下someArg1someArg2 arg不以---開頭,因此它是而不是的一個選項。默認情況下,這將排列在argv的末尾。 getopt的返回-1後,所有非選項ARGS將在argvoptindargc-1

while (iarg != -1) { 
    iarg = getopt_long(argc, argv, "s:vh", longopts, &index); 
    // ... 
} 

for (int i = optind; i < argc; i++) { 
    cout << "non-option arg: " << argv[i] << std::endl; 
} 

如果你添加一個-optstring開始,getopt將返回1(不是 '1' )和點optarg到非選項參數:

while (iarg != -1) { 
    iarg = getopt_long(argc, argv, "-s:vh", longopts, &index); 

    switch (iarg) 
    { 
     // ... 
     case 1: 
     std::cout << "You hit a non-option arg:" << optarg << std::endl; 
     break; 
    } 
} 
2

在線路./a.out --stuff someArg1 someArg2殼解釋三個參數的a.out。您希望shell解釋「someArg1 someArg2」作爲一個參數 - 所以把話說在報價:

./a.out --stuff "someArg1 someArg2" 
0

我工作的窗口,所以我不得不編譯的getopt和this excellent source

getopt_long

我修改了getopt_long.c(下面)以適應兩個輸入參數。我並沒有打擾多個爭論的更一般情況,因爲那需要比我有時間/需要更多(更清潔)的返工。第二個參數放在另一個全球性的「optarg2」中。

如果你不需要從源代碼編譯getopt,Frank上面的答案更加優雅。

extern char * optarg2 
. 
. 
. 
int getopt_long(nargc, nargv, options, long_options, index) 
{ 
. 
. 
. 
if (long_options[match].has_arg == required_argument || 
      long_options[match].has_arg == optional_argument || 
      long_options[match].has_arg == two_req_arguments) { 
      if (has_equal) 
       optarg = has_equal; 
      else 
       optarg = nargv[optind++]; 
      if (long_options[match].has_arg == two_req_arguments) { 
       optarg2 = nargv[optind++]; 
      } 
     } 
     if ((long_options[match].has_arg == required_argument || 
      long_options[match].has_arg == two_req_arguments) 
      && (optarg == NULL)) { 
      /* 
      * Missing argument, leading : 
      * indicates no error should be generated 
      */ 
      if ((opterr) && (*options != ':')) 
       (void)fprintf(stderr, 
        "%s: option requires an argument -- %s\n", 
        __progname(nargv[0]), current_argv); 
      return (BADARG); 
     } 
     if ((long_options[match].has_arg == two_req_arguments) 
      && (optarg2 == NULL)) { 
      /* 
      * Missing 2nd argument, leading : 
      * indicates no error should be generated 
      */ 
      if ((opterr) && (*options != ':')) 
       (void)fprintf(stderr, 
        "%s: option requires 2nd argument -- %s\n", 
        __progname(nargv[0]), current_argv); 
      return (BADARG); 
     } 

您還需要添加一個getopt.h定義「two_required_args」或「multiple_args」你認爲合適的。

編輯:我在降價不好