2017-08-28 12 views
0

Je sais qu'il y a déjà d'autres questions et réponses sur l'analyse de la ligne de commande args en c, mais j'espère que quelqu'un pourra me dire pourquoi mon code ne fonctionne pas. Voici mon code. Je veux analyser mes arguments sans en-têtes externes comme getopt.h /(unistd.h) ou args.hComment analyser les arguments de ligne de commande dans c sans getopt?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

void showUsage(char *prog) { 
    printf("Usage for %s...", prog); 
} 

int main(int argc, char *argv[]) { 

if (argc == 1) { 
    showUsage(argv[0]); 
    return EXIT_FAILURE; 
} 
int c; 
char *input, *output; 

for (c = 0; c < argc; ++c) { 
    if (strcmp((char *)argv[c], "-i")) { 
     input = (char *)argv[c + 1]; 
    } 
    if (strcmp((char *)argv[c], "-o")) { 
     output = (char *)argv[c + 1]; 
    } 
    } 
printf("\nInput %s Output: %s", input, output); 
return EXIT_SUCCESS; 
} 
+0

Quel est votre problème? Qu'attendez-vous pour un intrant donné? Qu'avez-vous observé? – Gerhardh

+0

Veuillez créer [MCVE] (https://stackoverflow.com/help/mcve) –

+2

Vous devriez commencer par 'c = 1', puisque' argv [0] 'est le nom du programme, pas un argument. – Barmar

Répondre

0

Le code suivant, je l'ai utilisé pendant des années pour analyser les commutateurs de ligne de commande de style unix. Adapt au besoin:

#include <stdio.h> 

int i, files; 
FILE *inf, *outf; 

int main (int argc, char *argv[]) 
{ 

    /* process switches; other prms are considered files (2) 
    that are opened for input/output. Files not specified 
    are taken as stdin and stdout. 
    */ 

    while (++i < argc) 
    switch (argv[i][0]) { 
     case '-': while (*++argv[i]) 
        switch (*argv[i]) { 
        case 'n': case 'N': 
         ++argv[i]; number= 0; 
         while (isdigit(*argv[i])) 
          number = number *10 + *argv[i]++ - '0'; 
         argv[i]--; 
         break; 

        case 'P' : printf ("Prm: P\n"); break; 
        case 'O' : printf ("Prm: O\n"); break; 
        default : 
        printf ("Bad switch %c, ignored.\n",*argv[i]); 
        } 
       break; 

     default : 
     switch (files) { 
     case 0: if ((inf=fopen(argv[i],"r")) == 0) 
        pexit("Input file %s not found.\n", argv[i]); 
       files++; break; 
     case 1: if ((outf=fopen(argv[i],"w")) == 0) 
        pexit (" Error creating output file %s.\n", argv[i]); 
       files++; break; 
     case 2: printf ("Too many file arguments: %s ignored.\n",argv[i]); 
       break; 
     } /* end switch files */ 
     } /* end switch argc */ 

    if (files <1) inf = stdin; 
    if (files <2) outf = stdout; 
} 
1

Il y a plusieurs problèmes avec votre code, mais le principal qui est la cause de vos problèmes est (comme le souligne Girouette out) que vous avez la valeur de retour de strcmp() vers l'arrière - il renvoie true si les chaînes sont différentes (en réalité, elle renvoie un nombre positif ou négatif indiquant laquelle des chaînes a le premier caractère le plus bas qui diffère, ou zéro si les chaînes sont identiques).

De plus, vous ne vérifiez pas qu'il existe un argument suivant l'argument -i ou -o. Considérez ce que votre code fera s'il est appelé comme progname -i

De plus, après avoir pris argv [c + 1] comme nom de fichier, vous n'incrémentez pas c, donc la prochaine fois que vous passerez dans la boucle, vous le ferez() Comme une option. Cela se casse si vous nommez votre fichier d'entrée -o, par exemple. Considérez comment vous allez analyser progname -i -o -o -i (certes un exemple artificiel, mais vous devriez être capable de gérer de telles choses).

De plus, la conversion de argv [c] en (char *) est inutile (c'est déjà un char *, et strcmp() prend un char * de toute façon, donc il aurait été auto-promu même s'il n'avait pas pas été). En général, tout ce casting réussit à vous cacher des bugs - si vous aviez mal écrit cela comme si vous appeliez strcmp(argv, "-i") le casting aurait caché votre erreur, donc vous auriez dû déboguer au lieu d'avoir le compilateur le signaler pour vous . Cela aurait été facile à trouver dans ce cas, mais lorsque vous travaillez sur un code plus complexe, cela peut prendre plusieurs jours.