2016-04-20 12 views
1

die Frage ist ziemlich klar, frage ich mich, weil der Mann sagtFunktionieren C getopt und getopt_long nur für Hauptargumente?

Die getopt() Funktion, um die Befehlszeilenargumente analysiert.

Und ich versuche es mit einer anderen Funktion zu verwenden, die die gleiche Signatur wie der Haupt hat und die argc und argv erhalten werden, mit wordexp so every scheint die gleichen, aber wenn getopt Aufruf erhalte ich einen Segmentierungsfehler unmittelbar nach getopt_long aufrufen.

#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; 
    } 
    } 


[...] 

Es könnte sein, dass, aber wenn so frage ich mich, warum es so ist auch, warum sollten wir die argc und argv-getopt (_long) übergeben.

Vielen Dank.

+0

Die einzige Annahme, die nicht oft angegeben wird, ist, dass Sie 'getopt()' et al konsistent mit den gleichen Werten für 'argc' und' argv' aufrufen, anstatt die Liste bei jedem Aufruf zu ändern. Wenn Sie 'getopt()' verwenden, um Befehlszeilenargumente zu verarbeiten, und sie anschließend verwenden, um auf andere Argumente zuzugreifen, könnten Sie Probleme bekommen. Machst du so etwas? (Im Prinzip gibt es keine Vorkehrungen für Nebenläufigkeit - es ist nicht Thread-sicher - und es gibt keine Vorkehrung für die Wiederverwendung. Es gibt normalerweise eine halb-undokumentierte Möglichkeit, das System so neu zu starten, aber es variiert.) –

+0

Keine Anrufe an 'getopt' kommen aus dem gleichen Thread und werden sequentiell ausgeführt. –

Antwort

3

Beide getopt() und getopt_long() funktioniert mit jedem richtigen char ** und int, gibt es keinen Unterschied zwischen argv und einer anderen char **. Wenn Sie argv und argc oder ihre Kopien von Haupt zu Ihrer Funktion übergeben und getopt() von dort aufrufen, wird es funktionieren. Zeigen Sie, wie Ihre Funktion argc und argv erhalten hat;

+0

Okay, cool. Ich sehe wirklich nicht, wo dieser Segmentierungsfehler herkommt ... Ich habe 'argv'-Werte vor einem Aufruf des Befehls (es ist ein Shell-Programm)' chat -h' gedruckt, der argv ist gut geparst und argc ist setze auf 2. Ich habe einen einfachen Aufruf von getopt ohne irgendeine while-Schleife versucht, gefolgt von einem Ausdruck des zurückgegebenen Wertes, und bekomme trotzdem den Segmentierungsfehler. Ich kann es von dem Aufruf zu "getopt_long" kommen, weil der Druck nicht gemacht ist. –

+0

Also rufst du getopt zweimal in deinem Programm an? Wenn Sie es zweimal aufrufen, müssen Sie 'optind' vor dem zweiten Aufruf auf '0' setzen. Und bieten mcve: https://StackOverflow.com/Help/Mcve – coredump

+0

Ich habe kommentiert die While-Schleife und ersetzte es mit einem einzigen Aufruf zu Getopt_Long und ich bekomme den Segmentierungsfehler, also ohne zweimal Anrufe, aber ich habe versucht, optind zu setzen vor dem ersten Anruf auf 0 und es funktioniert. Ich sehe es nicht in dem Mann. –