2012-11-26 22 views
0

我正在寫一些解析命令行輸入的代碼。我使用getopt_long的方法如下:getopt_long怪異的行爲

int c = 0; 
static struct option long_options[] = 
{ 
    {"mode",  1, NULL, 'm'}, 
    {"help",  0, NULL, 'h'}, 
    {0,    0, 0,  0} 
}; 
while ((c = getopt_long(argc, argv, "mh", long_options, NULL))!=-1) 
{ 
    switch(c) 
    { 
     case 0: 
     { 
      cerr<<"Usage: ./program <-m> <-h>"<<endl; 
      exit(1); 
      break; 
     } 
     case 'm': 
     { 
      if (!strcmp(optarg, "small")) 
       mode = 0; 
      else if (!strcmp(optarg, "medium")) 
       mode = 1; 
      else if (!strcmp(optarg, "large")) 
       mode = 2; 
      else{ 
       cerr<<"Invalid mode "<<optarg<<endl; 
       exit(1); 
      } 
      break; 
     } 
     case 'h': 
     { 
      cerr<<"See man page for help."<<endl; 
      exit(0); 
     } 
     default: 
     { 
      cerr<<"Unrecognized argument!"<<endl; 
      exit(1); 
     } 
    } 
} 

我測試了以下:

1)

./program 

程序不進入while循環。變量c被檢查爲-1。

2)

./program -h 

效果很好。

3)

./program -m small 

該程序退出與分段故障從投擲的strcmp()。

感謝您的任何幫助。

+1

在需要參數''m:h「'的選項後需要冒號。 – engineerC

+0

@CaptainMurphy謝謝!問題3)解決了,但1)仍然是 – ljhljh235

+2

如果你沒有選擇,getopt將不會執行任何操作。當沒有提供參數時,你想要做什麼? – engineerC

回答

1

下面是一個例子,如何用getopt_long()解析選項,並正確處理它的返回值,如期權,缺少參數和未知選項結束:

struct Options 
{ 
    std::string username = "guest"; 

    void parse_command_line(int ac, char** av) try { 
     enum { 
       HELP 
      , USER 
     }; 

     // This array must be in the same order as the enum. 
     option const options[] = { 
       {"help",   no_argument, nullptr, HELP} 
      , {"username", required_argument, nullptr, USER} 
      , {} 
     }; 

     ::opterr = 0; 
     for(int c; -1 != (c = getopt_long(ac, av, ":h", options, nullptr));) { 
      switch(c) { 
      // both short and long option 
      case 'h': 
      case HELP: 
       usage(av, EXIT_SUCCESS); 
       break; 

      // only long option 
      case USER: 
       username = ::optarg; // 
       break; 

      case ':': // missing argument 
       throw Exception("--%s: an argument required", options[::optopt].name); 

      case '?': // unknown option 
       throw Exception("%s: unknown option", av[optind - 1]); 
      } 
     } 

    } 
    catch(std::exception& e) { 
     fprintf(stderr, "error: %s\n", e.what()); 
     usage(av, EXIT_FAILURE); 
    } 
}; 

請注意,這是沒有必要有一個相應的每個多頭選項的短期選項。