2012-12-11 3 views
2

J'essaie d'analyser deux options dans un programme C.C: Options d'analyse dans le bon sens

Le programme est appelé comme ceci:

./a.out [OPTIONS] [DIRECTORY 1] [DIRECTORY 2] 

Le programme synchronise deux répertoires et a deux options. (-r) pour la synchronisation récursive (dossier à l'intérieur du dossier), et (-n) pour copier le fichier de local à distant au cas où il n'existe pas dans la télécommande.

Options are: 
-r : recursive 
-n : copy file if it doesn't exist in remote folder 

Donc, appeler:

./a.out -r D1 D2 

serait synchroniser récursive tous les fichiers et répertoires D1-D2. Les fichiers présents dans D1 et non présents dans D2 sont ignorés.

Et Vocation:

./a.cout -rn D1 D2 

ferait la même chose mais les fichiers présents dans D1 et non présent dans D2 sont copiés D2.

Le problème est que l'appel ./a.out -rn est pas la même chose que d'appeler ./a.out -nr et ./a.out -r -n ne fonctionne pas parce que ni (-n) n'est pas D1.

Voici comment j'implémente le main.

int main(int argc, char** argv) { 
    int next_option = 0; 
    const char* const short_options = "hrn:"; 

    const struct option long_options[] = { 
    { "help",  0, NULL, 'h' }, 
    { "recursive", 1, NULL, 'r' }, 
    { "new", 1, NULL, 'n' }, 
    { NULL,  0, NULL, 0 } 
    }; 

    int recursive = 0; 
    int new = 0; 

    do { 
    next_option = getopt_long(argc, argv, short_options, long_options, NULL); 

    switch(next_option) { 
     case 'r': 
     recursive = 1; 
     break; 

     case 'n': 
     new = 1; 
     break; 

     case 'h': 
     print_help(); 
     return 0; 

     case -1: 
     break; 

     default: 
     print_help(); 
     return -1; 
    } 

    } while(next_option != -1); 

    sync(argv[2], argv[3], recursive, new); 

    return EXIT_SUCCESS; 
} 
+2

De quelle façon est '-rn' pas la même chose que' -nr'? Votre mise en œuvre suggère que les deux devraient être équivalents. – ams

+0

Je vous assure que le résultat n'est pas le même. -rn = {resursive: 1, new: 1}, -nr = {resursive: 0, new: 1} – Alex

+2

Je vous suggère également de ne pas utiliser de mots-clés C++ (comme 'new') dans votre code. Bien que cela fonctionne aussi longtemps que vous utilisez un compilateur C, ce n'est pas portable si vous décidez dans le futur de passer en C++. –

Répondre

3

Vous avez deux problèmes (potentiels) ici:

  1. Vous avez une : parasite dans votre chaîne d'option courte. Cela fait -n prendre une option qui avale tout suivant r. Vous avez également les longues options définies pour prendre des arguments obligatoires.

  2. Vous avez durement codé les numéros d'argument de façon rigide, et vous ne testez pas qu'ils existent.

Essayez ceci:

int main(int argc, char** argv) { 
    int next_option = 0; 
    const char* const short_options = "hrn"; 
    extern int optind; 

    const struct option long_options[] = { 
    { "help",  no_argument, NULL, 'h' }, 
    { "recursive", no_argument, NULL, 'r' }, 
    { "new",  no_argument, NULL, 'n' }, 
    { NULL,  no_argument, NULL, 0 } 
    }; 

    int recursive = 0; 
    int new = 0; 

    do { 
    next_option = getopt_long(argc, argv, short_options, long_options, NULL); 

    switch(next_option) { 
     case 'r': 
     recursive = 1; 
     break; 

     case 'n': 
     new = 1; 
     break; 

     case 'h': 
     print_help(); 
     return 0; 

     case -1: 
     break; 

     default: 
     print_help(); 
     return -1; 
    } 

    } while(next_option != -1); 

    if (optind + 1 >= argc) 
    return -1; 

    sync(argv[optind], argv[optind+1], recursive, new); 

    return EXIT_SUCCESS; 
} 
1

Le problème avec l'utilisation d'une ligne de commande telle que -r -n est parce que vous avez codé en dur les index dans l'appel à sync. Tu ne devrais pas faire ça.

Si vous lisez la getopt_long page de manuel (toujours faire lorsque vous avez des problèmes avec une fonction!) Alors vous remarquerez cette ligne:

S'il n'y a plus de caractères d'option, getopt() retours -1. Puis optind est l'index dans argv du premier argv -element qui n'est pas une option.

Lisez attentivement la deuxième phrase.

+0

C'est vrai, mais ce n'est pas vraiment le problème OP. Notez qu'il n'a jamais dit '-r -n', il a dit' -rn', et dans ce cas le code était mauvais mais pas cassé. – ams

+0

@ams Juste après le '-rn' versus' -nr', l'OP dit qu'il y a aussi un problème avec '-r -n'. –

+0

Oh oui, je n'ai pas vu ça à cause de la coupure de ligne. Mon erreur. – ams

Questions connexes