问题
After doing some reading on this link on how to use getopt()
, I'm trying to get a small example.
What I want, is something like:
./prog -v # show me prog version
./prog -f filename # just show me the filename I entered from the command line
Here is what I wrote so far:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int
main(int argc, *argv[]) {
char VER[] = "0.1.1";
int opt;
opt = getopt(argc, argv, "vf:");
char *filename;
while (opt != -1) {
switch(opt) {
case 'v':
printf("version is %s", VER);
break;
case 'f':
filename = optarg;
break;
}
}
printf("The filename was %s", filename);
return 0;
}
I compile the code with:
$ gcc prog.c -o prog -Wall -Wextra
I can't seem to understand when I run it with -v
option it never stops printing the version
and with -f filename
it stops there and never prints the filename I entered.
回答1:
It doesn't stop because you only call getopt()
once. A possible fix:
#include <stdio.h>
#include <unistd.h>
int
main(int argc, char **argv)
{
char VER[] = "0.1.1";
int opt;
const char *filename = "unspecified";
while ((opt = getopt(argc, argv, "vf:")) != -1)
{
switch (opt)
{
case 'v':
printf("version is %s\n", VER);
break;
case 'f':
filename = optarg;
break;
default:
fprintf(stderr, "Usage: %s [-v][-f file]\n", argv[0]);
return(1);
}
}
printf("The filename was %s\n", filename);
return 0;
}
Note that I've made sure that filename
is initialized, that printf()
outputs end with a newline, and that the error cases are reported.
Here's another, slightly more complex, example program:
/* Example 1 - using POSIX standard getopt() */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char **argv)
{
int opt;
int i;
int bflag = 0;
int aflag = 0;
int errflag = 0;
char *ifile = 0;
char *ofile = 0;
while ((opt = getopt(argc, argv, ":abf:o:")) != -1)
{
switch (opt)
{
case 'a':
if (bflag)
errflag++;
else
aflag++;
break;
case 'b':
if (aflag)
errflag++;
else
bflag++;
break;
case 'f':
ifile = optarg;
break;
case 'o':
ofile = optarg;
break;
case ':': /* -f or -o without operand */
fprintf(stderr, "Option -%c requires an operand\n", optopt);
errflag++;
break;
case '?':
default:
fprintf(stderr, "Unrecognized option: -%c\n", optopt);
errflag++;
break;
}
}
if (errflag)
{
fprintf(stderr, "Usage: %s [-a|-b][-f in][-o out] [file ...]\n", argv[0]);
exit(2);
}
printf("Flags: a = %d, b = %d\n", aflag, bflag);
if (ifile != 0)
printf("Input: %s\n", ifile);
if (ofile != 0)
printf("Output: %s\n", ofile);
printf("Argc = %d, OptInd = %d\n", argc, optind);
for (i = optind; i < argc; i++)
printf("File: %s\n", argv[i]);
return(EXIT_SUCCESS);
}
It is based on an example from a Sun manual. The -a
and -b
options are mutually exclusive. It illustrates (the limitations of) POSIX getopt()
with 'optional arguments' enabled (the leading :
on the option string). It also prints out its inputs at the end.
回答2:
Here:
case 'v':
printf("version is %s", VER);
break;
the break
is breaking you out of the switch
statement, not out of the while
loop, so the while
loop continues and you go on forever because opt
never changes. You're missing some logic, here, you probably want to be calling getopt()
again somewhere in the loop.
回答3:
int main(int argc, *argv[], "vf")
getopt.c:5:20: error: expected declaration specifiers or â...â before â*â token
getopt.c:5:28: error: expected declaration specifiers or â...â before string constant
this should be
int main(int argc, char *argv[] )
modified code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char VER[] = "0.1.1";
int opt;
opt = getopt(argc, argv, "vf:");
char *filename;
while (opt != -1) {
switch(opt) {
case 'v':
printf("version is %s\n", VER);
exit(0);
case 'f':
// filename = optarg;
printf("The filename was %s\n", argv[2]);
exit(0);
}
}
return 0;
来源:https://stackoverflow.com/questions/18554775/the-simplest-possible-getopt-program-i-can-get