Parsing the Command Line IV

Command line options often sport their own options or settings. For example, tab width might be set by specifying the tabwidth option followed by a value. No hard and fast rules exist for how such an option is set, but I’ve seen it happen in one of three ways:

First, the option uses an equal sign, such as:

program tabwidth=8

Second, is a more compact version of that argument:

program t8

Third, the option is separated from its setting by using whitespace:

program tabwidth 8

And, of course, variations on each of these methods are used. In Unix, options are often prefixed by one or two dashes, which help visually separate options from file names, although that usage isn’t consistent. In Windows (DOS), a forward slash is used instead of a dash.

To keep the user from going insane, your program’s documentation lists the proper format, which is usually consistent with whatever options are used in other, similar programs. You can be as strict or lenient as you like, providing that your code properly interprets the user’s intentions.

In the code below, the argument format is tabwidth=8. No white space appears before or after the equal sign:

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

int main(int argc, char *argv[])
{
    int x,tabwidth;
    char *value;

    tabwidth = 8;       /* set default */

    for(x=1;x<argc;x++)
    {
        if( strncmp(argv[x],"tabwidth=",9) == 0 )
        {
            value = argv[x];
            value += 9;
            tabwidth = atoi(value);
        }
    }
    printf("Tab width set to %d\n",tabwidth);

    return(0);
}

In Line 14, I use the strncmp() function to compare only the first 9 characters of the option’s text. These characters include the equal sign. The value pointer is adjusted to reference the start of whatever number is specified. The atoi() function at Line 18 fetches the proper value.

When the t8 argument format is used, a similar approach fetches the value. In this case, the strncmp() function isn’t needed because only a single character is being compared:

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

int main(int argc, char *argv[])
{
    int x,tabwidth;
    char *value;

    tabwidth = 8;       /* set default */

    for(x=1;x<argc;x++)
    {
        value = argv[x];
        if( *value == 't')
        {
            value++;
            tabwidth = atoi(value);
        }
    }
    printf("Tab width set to %d\n",tabwidth);

    return(0);
}

At Line 14, the code checks to see whether a t was specified. If so, the value pointer is incremented and then the atoi() function fetches the value.

This single letter/value approach is really cryptic, but experienced users prefer to type fewer characters. That explains why you see it used so often.

Another way to specify an option’s settings is to separate both with whitespace. The consequence of this approach is that a single option becomes two command line arguments. The following code shows one way to process such options:

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

int main(int argc, char *argv[])
{
    int x,tabwidth;
    char *value;

    tabwidth = 8;       /* set default */

    for(x=1;x<argc;x++)
    {
        if( strcmp(argv[x],"tabwidth") == 0 )
        {
            if( x+1 < argc)
                tabwidth = atoi(argv[x+1]);
            else
                fprintf(stderr,"Missing value\n");
        }
    }
    printf("Tab width set to %d\n",tabwidth);

    return(0);
}

Line 15 ensures that the option is present: When the option is specified, the value of x is always less than the argument count.

While each of these samples processes the tabwidth option, no further checking is done on that value. In a real program, bounds checking would take place to ensure that unusable values (negative numbers, zero, or large values) would be eliminated.

Finally, I’ve seen command line arguments that specify a range of numbers, such as:

program range=3,10

This format simply presents additional string processing, expanding upon what’s demonstrated in this Lesson’s first example.

Leave a Reply