Question

Je suis en train d'analyser les arguments dans la ligne de commande à l'aide switch et getopt(). La structure est très simple: j'ai un makefile, un .c et un fichier .h. Ceci est la première fois que je l'aide du commutateur, alors je pourrais faire quelques erreurs de base. Je l'ai utilisé ce lien comme guide pour commutateur et Si vous voyez des erreurs de base Veuillez me le faire savoir.

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
Était-ce utile?

La solution

Ne pas oublier que « default » a « a » en elle -. Vous venez de code avec une étiquette indiquant qu'ils l'étiquette (non utilisée) defult, plutôt que compte tenu de l'interrupteur d'un cas par défaut

On ne sait pas pourquoi vous pensez que optopt pourrait être « c » ou doit être traitée spécialement quand il est « c »; il pourrait être une gueule de bois d'une édition antérieure.

Vous traitez le « g » et « t » options que si elles prennent des arguments, mais l'appel à getopt() ne pas la liste après les deux points. Si l'interrupteur est à croire, vous avez besoin que l'argument soit "g:t:f:".

En outre, vous devriez utiliser le char * appelé optarg au lieu d'essayer d'utiliser argv[optind]. Vous utilisez optind après que la boucle a terminé à traiter des arguments supplémentaires ( "nom de fichier).

En outre, étant donné que gravity et thrust sont des nombres 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, appelez une fonction pour faire les rapports de vérification et d'erreurs.

Je recommande de mettre des accolades autour de la déclaration de switch, ou autour du corps de la déclaration de 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 les accolades supplémentaires. Pour une seule instruction de ligne, je n'ai aucun problème; mais pour une déclaration complexe comme l'interrupteur, je recommande les accolades supplémentaires.

doit être à l'extérieur "return 0; la boucle for. À l'heure actuelle, la boucle arrête le premier argument non-option.


Le makefile est fondamentalement bien. Finalement, vous allez utiliser plusieurs macros et plus de drapeaux d'avertissement de compilation, mais les seuls problèmes que je remarquai que le compilateur est également l'endroit était la faute de frappe dans le cas par défaut et la non-conversion de chaînes en nombres 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 $@ ${OBJECT} ${LDFLAGS} ${LDLIBS}

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

clean:
    -rm -f *.o ${PROGRAM} core
scroll top