2016-04-20 43 views
1

問題是很清楚,我不知道是因爲男人說C getopt和getopt_long只適用於主參數嗎?

的getopt()函數解析命令行參數。

,我試圖與具有相同簽名爲主體和argcargvwordexp所以萬物得到另一個函數使用它似乎是相同的,但調用getopt的,當我後,立即得到一個分段錯誤調用getopt_long。

#define OPT_HELP 'h' 
#define OPTL_HELP "help" 
#define OPT_MESS 'm' 
#define OPTL_MESS "message" 

#define OPT_STRING "hm:" 

struct option longopts[] = { 
    {OPTL_HELP,  no_argument, 0, OPT_HELP}, 
    {OPTL_MESS,  required_argument, 0, OPT_MESS}, 
    {0, 0, 0, 0} 
}; 

#define FLAG_MESS 1 

void cmd_chat(int argc, char **argv) 
{ 
    int c, indexptr; 
    short flag = 0; 
    char message[481]; 
    while ((c = getopt_long(argc, argv, OPT_STRING, 
      longopts, &indexptr)) != -1) { 
    debug(MAGENTA "cmd_chat", MAGENTA "c value: %d", c); 
    switch (c) { 
     case OPT_HELP: 
     debug(MAGENTA "cmd_chat", MAGENTA "calling help"); 
     help(argv[0]); 
     return; 
     break; 
     case OPT_MESS: 
     flag |= FLAG_MESS; 
     strncpy(message, optarg, 481); 
     break; 
     default: 
     usage(argv[0]); 
     break; 
    } 
    } 


[...] 

這可能是,但即便如此我不知道爲什麼它是這樣也是爲什麼我們應該通過argcargvgetopt_long)。

謝謝。

+0

不經常提到的一個假設是,您可以一致地調用'getopt()'等以及'argc'和'argv'的相同值,而不是在每次調用時更改列表。如果你使用'getopt()'來處理命令行參數,然後用它來訪問一些其他的參數集,你可以 - 不一定會 - 遇到問題。你在做那樣的事嗎? (基本上,並沒有提供併發 - 它不是線程安全的 - 並且沒有提供重用。通常有一個半未記錄的方式來重置系統,以便它重新開始,但它會變化。) –

+0

沒有調用'getopt'來自同一個線程,所以順序執行。 –

回答

3

兩個getopt()getopt_long()都會在每一個適當char **int工作,有argv和任何其他char **之間沒有什麼區別。 如果您將通過argvargc,或從主副本到您的功能,並從那裏調用getopt()它將工作。顯示你的功能如何得到argcargv;

+0

好吧,很酷。我真的不知道分段錯誤來自哪裏...... 我在打電話給命令(它是一個shell程序)'chat -h'之前打印了'argv'值,argv分析得很好,而argc是設置爲2.我嘗試了一個簡單的調用getopt而沒有任何'while'循環,之後立即打印返回的值,並且仍然出現了段錯誤。我可以看到它來自'getopt_long'的調用,因爲打印沒有完成。 –

+0

那麼你在程序中調用兩次getopt?如果你調用它兩次,你需要在第二次調用之前將'optind'設置爲'0'。並提供mcve:https://stackoverflow.com/help/mcve – coredump

+0

我已經評論了while循環,並用一次調用getopt_long替換了它,並且我得到了段錯誤,所以沒有兩次調用,但我試圖設置optind在第一次通話之前爲0,並且它工作。我在男人身上看不到它。 –