A command-line parser that can be used by applications that follow Unix command-line conventions.
#include <unistd.h> (X/Open, POSIX-1) #include <stdio.h> (X/Open, POSIX-2) int getopt (int argc, char * const argv[], const char *optstring); extern char *optarg; extern int optind, opterr, optopt;
The getopt function returns the next option character (if one is found) from argv that matches a character in optstring, if there is one that matches. If the option takes an argument, getopt sets the variable optarg to point to the option-argument as follows:
If one of the following is true, getopt returns -1 without changing optind:
If argv[optind] points to the string "- -" getopt returns -1 after incrementing optind.
If getopt encounters an option character not contained in optstring, the question-mark character (?) is returned.
If getopt detects a missing argument, the colon character (:) is returned if the first character of optstring is a colon; otherwise a question-mark character is returned.
In either of the previous two cases, getopt sets the variable optopt to the option character that caused the error. If the application has not set the variable opterr to 0 and the first character of optstring is not a colon, getopt also prints a diagnostic message to stderr.
x | The next option character specified
on the command line.
A colon is returned if getopt detects a missing argument and the first character of optstring is a colon. A question mark is returned if getopt encounters an option character not in optstring or detects a missing argument and the first character of optstring is not a colon. |
-1 | When all command-line options are parsed. |
The following example shows how you might process the arguments for a utility that can take the mutually exclusive options a and b and the options f and o, both of which require arguments:
#include <unistd.h> int main (int argc, char *argv[ ]) { int c; int bflg, aflg, errflg; char *ifile; char *ofile; extern char *optarg; extern int optind, optopt; . . . while ((c = getopt(argc, argv, ":abf:o:)) != -1) { switch (c) { case 'a': if (bflg) errflg++; else aflg++; break; case 'b': if (aflg) errflg++; else { bflg++; bproc(); } 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); errflg++; break; case '?': fprintf (stderr, "Unrecognized option -%c\n"' optopt); errflg++; } } if (errflg) { fprintf (stderr, "usage: ..."); exit(2); } for ( ; optind < argc; optind++) { if (access(argv[optind], R_OK)) { . . . }
This sample code accepts any of the following as equivalent:
cmd -ao arg path path cmd -a -o arg path path cmd -o arg -a path path cmd -a -o arg -- path path cmd -a -oarg path path cmd -aoarg path path