2010-11-26 7 views
0

J'essaye d'analyser les arguments dans la ligne de commande en utilisant switch et getopt(). La structure est très facile: j'ai un makefile, un .c et un fichier .h. C'est la première fois que j'utilise switch, donc je peux faire quelques erreurs basiques. J'ai utilisé ce lien comme guide pour passer link text et link text Si vous voyez des erreurs de base s'il vous plaît faites le moi savoir.instruction switch et fonction getopt() dans C

makefile:

make:lunar 

lunar: lunar.o 
    gcc -Wall -std=c99 -g -o lunar lunar.o -lm 
lunar.o: lunar.c lunar.h 
    gcc -Wall -std=c99 -g -c lunar.c 

clean: 
    -rm -f *.o lunar core 

/////////////////////////////////////

lunar.c

int main (int argc, char *argv[]){ 
    int i; 
    int c = 0; 
    int gravity = 0; 
    int thrust = 0; 
    opterr = 0; 
    while ((c = getopt (argc, argv, "gtf:")) != -1) 
     switch (c){ 
      case 'g': 
       gravity = argv[optind]; 
       break; 
      case 't': 
       thrust = argv[optind]; 
       break; 
      case 'f': 
       argument = argv[optind]; 
       break; 
      case '?': 
       if (optopt == 'c') 
        fprintf(stderr, "Option -%c requires 
          an argument.\n", optopt); 
       else if (isprint (optopt)) 
        fprintf (stderr, "Unknown option 
          `-%c'.\n", optopt); 
       else 
        fprintf (stderr, "Unknown option 
          character `\\x%x'.\n", 
          optopt); 
       return 1; 
      defult: 
       abort(); 
     } 
    printf ("gravity is %d and thrust is %d.\n", 
      gravity, thrust); 
    for (int index = optind ; index < argc ; index++){ 
     printf ("Non-option argument %s\n", argv[index]); 
     return 0; 
    } 
} 

///////////////////////////////////

lunar.h

#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 
#include <stdlib.h> 
#include <math.h> 
#include <unistd.h> 
#include <assert.h> 

#define MAX_WORD 256 

Répondre

4

N'oubliez pas que 'default' a un 'a' dedans - vous venez d'étiqueter ce code avec l'étiquette (non utilisée) defult, plutôt que de donner au commutateur un cas par défaut.

Il n'est pas clair pourquoi vous pensez que optopt pourrait être 'c' ou devrait être traité spécialement quand c'est 'c'; il pourrait être une gueule de bois d'une édition antérieure.

Vous traitez les options 'g' et 't' comme si elles prenaient des arguments, mais l'appel à getopt() ne liste pas les deux-points après eux. Si le commutateur doit être cru, vous avez besoin que l'argument soit "g:t:f:". En outre, vous devez utiliser le char * appelé optarg au lieu d'essayer d'utiliser argv[optind]. Vous utilisez optind après la fin de la boucle pour traiter les arguments supplémentaires ('nom de fichier').

En outre, puisque gravity et thrust sont des entiers, vous devez convertir les chaînes en nombres entiers. La façon facile (en ignorant largement les erreurs possibles) est avec:

gravity = atoi(optarg); 

Si vous voulez faire le traitement des erreurs, appeler une fonction pour faire les rapports de vérification et d'erreurs.

Je mettais des accolades autour recommande la déclaration switch, ou autour du corps de la déclaration while:

while ((c = getopt(argc, argv, "g:f:t:")) != -1) 
{ 
    switch (c) 
    { 
    ... 
    } 
} 

Il est pas strictement nécessaire, mais il est (IMNSHO) plus facile à lire le code avec le supplément bretelles. Pour une déclaration de ligne unique, je n'aurais aucun problème; mais pour une déclaration complexe comme le commutateur, je recommande les accolades supplémentaires. Le 'return 0;' doit être en dehors de la boucle for. À l'heure actuelle, la boucle s'arrête sur le premier argument sans option.


Le fichier makefile est fondamentalement correct.Finalement, vous utiliserez plus de macros et plus de drapeaux d'avertissement de compilation, mais les seuls problèmes que j'ai repérés que le compilateur pourrait également détecter sont la faute de frappe dans le cas par défaut et la non-conversion des chaînes en entiers.

PROGRAM = lunar 
SOURCE = lunar.c 
HEADER = ${SOURCE:.c=.h} 
OBJECT = ${SOURCE:.c=.o} 
CFLAGS = -std=c99 -Wall -g 
LDFLAGS = 
LDLIBS = -lm 

all: ${PROGRAM} 

${PROGRAM}: ${OBJECT} 
    ${CC} ${CFLAGS} -o [email protected] ${OBJECT} ${LDFLAGS} ${LDLIBS} 

${OBJECT}: ${SOURCE} ${HEADER} 
    ${CC} ${CFLAGS} -c ${SOURCE} 

clean: 
    -rm -f *.o ${PROGRAM} core 
+0

Merci. Je l'ai. –

Questions connexes