Reputation: 148
I'm new to C and trying to use getopt combined with a switch statement. I think my problem is just a syntax one but I can't seem to figure it out. I need to run my program like this :
$/webserver -p 8080 -r /my/root/dir
.
So I need to recognize the -p and get the 8080 and the recognize the -r and get the /my/root/dir. Currently my code finds the -p and then finds the -r and then detects an unknown option and exits. Here is the code. I have the puts()
in there for testing.
#define USAGE_STRING "Usage: webserver -p <port> -r <rootdir>\n"
char *port;
char *rootdir;
// Process command line arguments. Uses GNU getopt() function.
void processargs(int argc, char **argv) {
int next_option;
do {
next_option = getopt(argc, argv, "pr:");
if (next_option != -1) {
switch (next_option)
{
case 'p': /* -p -- port option */
puts("p");
port = optarg;
printf("%s", port);
case 'r': // -r -- root directory option
puts("r");
rootdir = optarg;
printf("%s", rootdir);
default:
puts("unknown");
/* Unknown option detected. Print it to standard
output, and exit with exit code zero (normal termination). */
fprintf(stderr, USAGE_STRING);
exit(1);
}
}
} while (next_option != -1);
printf("%s", port);
if (port == NULL) {
fprintf(stderr, USAGE_STRING);
exit(1);
}
if (rootdir == NULL) {
puts("unknown");
fprintf(stderr, USAGE_STRING);
exit(1);
}
}
Currently when I run the above command I get this output (using the puts for testing).
p
r
unknown
Usage: webserver -p <port> -r <rootdir>
Thanks for any help!
Upvotes: 0
Views: 962
Reputation: 1383
First you should be using getopt_long()
I believe getopt()
is depreciated. You are also missing break
in your switch statement. With out break each case beneath that one will be executed. While you could use a do-while loop it's simpler to just use a while loop.
Here's a simple command line parser you can build on.
static const char *optstring = "p:r:";
static struct option longopts[] =
{
{ "port", required_argument, NULL, 'p' },
{ "root", required_argument, NULL, 'r' },
{ NULL, 0, NULL, 0 }
};
int parseInput(int argc, char * const argv[])
{
int ch;
/* Main Loop ie the Parser */
while ((ch = getopt_long(argc, argv, optstring, longopts, NULL)) != -1)
{
switch(ch)
{
case 'p':
printf("arg: %s\n", optarg);
break;
case 'r':
printf("arg: %s\n", optarg);
break;
default:
printf("Unsupported option\n");
return -1;
}
}
return 0;
}
Upvotes: 0
Reputation: 58274
A C switch statement requires a break
at the end of each case, otherwise the code in the following case is executed. So this:
switch (next_option)
{
case 'p': /* -p -- port option */
puts("p");
port = optarg;
printf("%s", port);
case 'r': // -r -- root directory option
puts("r");
rootdir = optarg;
printf("%s", rootdir);
default:
puts("unknown");
/* Unknown option detected. Print it to standard output, and exit with exit code zero
(normal termination). */
fprintf(stderr, USAGE_STRING);
exit(1);
}
Must be changed to this:
switch (next_option)
{
case 'p': /* -p -- port option */
puts("p");
port = optarg;
printf("%s", port);
break;
case 'r': // -r -- root directory option
puts("r");
rootdir = optarg;
printf("%s", rootdir);
break;
default:
puts("unknown");
/* Unknown option detected. Print it to standard output, and exit with exit code zero
(normal termination). */
fprintf(stderr, USAGE_STRING);
exit(1);
}
Upvotes: 1
Reputation: 11
I believe you want to use break
at the end of each case, else execution falls through to the next case block.
Upvotes: 1