Discovering Command Line Options, Part II

I suppose smart equates to quirky in most programming circumstances. This maxim definitely holds true for the getopt() function. Before you can appreciate this function and put it to use, you must understand how it works and why it can be quirky.

Here is a sample getopt() statement:

r = getopt(argc,argv,"ABC");

The argc and argv arguments are stolen directly from the main() function. The third argument implies that this program can swallow up to three optional switches: -A, -B, and -C. These must be specified with the leading dash and the letters are case sensitive. Here is the full code:

2021_07_03-Lesson-a.c

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int r;

    r = getopt(argc,argv,"ABC");
    printf("The getopt() function returned %d\n",r);

    return(0);
}

The getopt() function at Line 8 reads the command line arguments. The return value from the function, stored in variable r, is output as an integer at Line 9. The purpose of this program is to discover how getopt() processes input. Sample runs are in order, first with no arguments:

$ ./a.out
The getopt() function returned -1

The return value of -1 means that all command line arguments have been parsed. It would be up to the code at this point to determine whether this condition is wanted or valid. Remember, the return value of -1 isn’t really an error, just a value open to interpretation.

Next, the valid switch -A is specified:

$ ./a.out -A
The getopt() function returned 65

The function returned the ASCII code value for 'A', 65. Note that the switch is specified as -A. Here’s what you see when just A is specified:

$ ./a.out A
The getopt() function returned -1

The function returns -1 for an unrecognized argument. Because the A isn’t prefixed with a dash, the function assumes it’s something other than a switch; the getopt() function ignores command line arguments not prefixed with a dash.

Here is the function’s reaction when you type a little -a as a switch:

$ ./a.out -a
./a.out: illegal option -- a
The getopt() function returned 63

The first line of output is generated by the getopt() function itself: -a is an “illegal” option. But the program continues, the printf() generating it output: The code presented is ASCII 63, the '?' character.

The ugly error message is output by default, though you can suppress it. To do so, set the global variable opterr to zero. This variable is an extern int defined in the unistd.h header file. Here’s is the updated code:

2021_07_03-Lesson-b.c

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int r;

    opterr = 0;
    r = getopt(argc,argv,"ABC");
    printf("The getopt() function returned %d\n",r);

    return(0);
}

Here is the output with the opterr variable set to zero (Line 8 above):

$ ./a.out -a
The getopt() function returned 63

The takeaway here is that return code 63 indicates an invalid option. Your code can do whatever in such a circumstance.

One last test! The final character in the third argument, C:

$ ./a.out -C
The getopt() function returned 67

ASCII code 67 represents a ‘C’.

Each option is detected. Bogus options return value 63, the '?' character. Next week’s Lesson continues exploration of the getopt() function, with the method to review multiple options and how to determine what character was specified as an invalid option.

Leave a Reply