Reputation: 1324
I am trying to parse the arguments in the command line using switch
and getopt()
. The structure is very easy: I have a makefile
, a .c
and a .h
file. This is the first time that I am using switch, so I might be doing some basic mistakes. I have used this link as my guide to switch
link text
and
link text
If you see any basic mistakes please let me know.
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
Upvotes: 0
Views: 2867
Reputation: 754150
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
Upvotes: 4