Bulat M. Bulat M. - 1 month ago 7
C Question

How could one determine that required argument of option is missing?

I use

getopt_long
on GNU/Linux machine.
Initialize options list as:

static struct option long_options[] = {
{"mode", required_argument, 0, 9},
{0, 0, 0, 0}
};


Have following line of code

c = getopt_long(argc, argv, "", long_options, index_ptr);


When I run my program with command:

prog --mode


Above shown line of code returns '?' in c, but not ':' as expected according to
getopt(3)
man page: "Error and -1 returns are the
same as for getopt()"


Yes, when using/parsing short options one could write in options list something like ":m:", so that variable c on missing argument would contain ':', not '?', but what one should do to distinguish between two cases(missing argument, invalid option) when parsing only long options?

How could one distinguish between invalid option and option with missing required argument?

Answer

The only way that I can see to accomplish your goal of distinguishing between an invalid option and a valid option with a missing argument is to set the has_arg field of the options struct to optional_argument, and then to test manually for an argument. Then getopt_long() will only return a value of '?' when there is an invalid option, and you can check to see if a specified option has an argument by looking in optarg. Here is an example:

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

int main(int argc, char *argv[])
{
    int i, opt;
    int index = -1;

    static struct option long_options[] = {
        {"mode", optional_argument, NULL, 'm'},
        {0, 0, 0, 0}
    };

    /* suppress error messages */
    //opterr = 0;

    while ((opt = getopt_long(argc, argv, "", long_options, &index)) != -1) {
        if (opt == '?') {
            /* do something, perhaps: */
            //printf("Invalid option \n");
            //      exit(EXIT_FAILURE);
        }
        if (opt == 'm' && optarg == NULL) {
            printf("Missing argument in '--mode' option\n");
            exit(EXIT_FAILURE);
        }        
    }

    return 0;
}
Comments