0

我正在尝试使用switch和解析命令行中的参数getopt()。结构很简单:我有一个makefile,一个.c和一个.h文件。这是我第一次使用switch,所以我可能会犯一些基本错误。我已使用此链接作为切换 链接文本链接文本的指南 如果您发现任何基本错误,请告诉我。

生成文件:

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

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

月球.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;
    }
}

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

月球.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
4

1 回答 1

4

Don't forget that 'default' has an 'a' in it - you've just labelled that code with the (unused) label defult, rather than given the switch a default case.

It is not clear why you think optopt could be 'c' or should be treated specially when it is 'c'; it might be a hangover from an earlier edition.

You are processing the 'g' and 't' options as if they take arguments, but the call to getopt() does not list colons after them. If the switch is to be believed, you need the argument to be "g:t:f:".

Also, you should be using the char * called optarg instead of trying to use argv[optind]. You use optind after the loop has finished to process extra ('file name') arguments.

Also, since gravity and thrust are integers, you need to convert the strings into integers. The easy way (largely ignoring possible errors) is with:

gravity = atoi(optarg);

If you want to do error handling, call a function to do the checking and error reporting.

I recommend putting braces around the switch statement, or around the body of the while statement:

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

It isn't strictly necessary, but it is (IMNSHO) easier to read the code with the extra braces. For a single line statement, I'd have no problem; but for a complex statement like the switch, I recommend the extra braces.

The 'return 0;' should be outside the for loop. At the moment, the loop stops on the first non-option argument.


The makefile is basically fine. Eventually, you'll use more macros and more compilation warning flags, but the only problems that I spotted that the compiler would also spot were the typo in the default case and the non-conversion of strings into integers.

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
于 2010-11-26T04:35:26.020 回答