Next: , Previous: Example of Getopt, Up: Getopt


25.2.3 Parsing Long Options with getopt_long

To accept GNU-style long options as well as single-character options, use getopt_long instead of getopt. This function is declared in getopt.h, not unistd.h. You should make every program accept long options if it uses any options, for this takes little extra work and helps beginners remember how to use the program.

— Data Type: struct option

This structure describes a single long option name for the sake of getopt_long. The argument longopts must be an array of these structures, one for each long option. Terminate the array with an element containing all zeros.

The struct option structure has these fields:

const char *name
This field is the name of the option. It is a string.
int has_arg
This field says whether the option takes an argument. It is an integer, and there are three legitimate values: no_argument, required_argument and optional_argument.
int *flag
int val
These fields control how to report or act on the option when it occurs.

If flag is a null pointer, then the val is a value which identifies this option. Often these values are chosen to uniquely identify particular long options.

If flag is not a null pointer, it should be the address of an int variable which is the flag for this option. The value in val is the value to store in the flag to indicate that the option was seen.

— Function: int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *indexptr)

Decode options from the vector argv (whose length is argc). The argument shortopts describes the short options to accept, just as it does in getopt. The argument longopts describes the long options to accept (see above).

When getopt_long encounters a short option, it does the same thing that getopt would do: it returns the character code for the option, and stores the options argument (if it has one) in optarg.

When getopt_long encounters a long option, it takes actions based on the flag and val fields of the definition of that option.

If flag is a null pointer, then getopt_long returns the contents of val to indicate which option it found. You should arrange distinct values in the val field for options with different meanings, so you can decode these values after getopt_long returns. If the long option is equivalent to a short option, you can use the short option's character code in val.

If flag is not a null pointer, that means this option should just set a flag in the program. The flag is a variable of type int that you define. Put the address of the flag in the flag field. Put in the val field the value you would like this option to store in the flag. In this case, getopt_long returns 0.

For any long option, getopt_long tells you the index in the array longopts of the options definition, by storing it into *indexptr. You can get the name of the option with longopts[*indexptr].name. So you can distinguish among long options either by the values in their val fields or by their indices. You can also distinguish in this way among long options that set flags.

When a long option has an argument, getopt_long puts the argument value in the variable optarg before returning. When the option has no argument, the value in optarg is a null pointer. This is how you can tell whether an optional argument was supplied.

When getopt_long has no more options to handle, it returns -1, and leaves in the variable optind the index in argv of the next remaining argument.

Since long option names were used before before the getopt_long options was invented there are program interfaces which require programs to recognize options like ‘-option value instead of ‘--option value. To enable these programs to use the GNU getopt functionality there is one more function available.

— Function: int getopt_long_only (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *indexptr)

The getopt_long_only function is equivalent to the getopt_long function but it allows to specify the user of the application to pass long options with only ‘-’ instead of ‘--’. The ‘--’ prefix is still recognized but instead of looking through the short options if a ‘-’ is seen it is first tried whether this parameter names a long option. If not, it is parsed as a short option.

Assuming getopt_long_only is used starting an application with

            app -foo

the getopt_long_only will first look for a long option named ‘foo’. If this is not found, the short options ‘f’, ‘o’, and again ‘o’ are recognized.