eddiewastaken
eddiewastaken

Reputation: 832

Switch case not affecting variable C

int main (int argc, char **argv) {
    //Initialise variable for switch option
    int option = 0;
    //Set time to default to epoch
    char *argtime = "1970-01-01 00:00:00";
    //Use getopt to parse switches t and h (neither requires an argument, as epoch is defaulted to if non is supplied)
    while ((option = getopt(argc, argv, "th")) != -1) {
        //Switch statements for supplied switches
        switch (option) {
            //If -t
            case 't':
                //If arg supplied
                if(optarg != NULL) {
                    //Set arg to given arg 
                    argtime = optarg;
                }
                printf("-t is selected.\n");
                break;
            //If -h
            case 'h':
                printf("Help is selected\n");
                break;
            //If anything else
            default:
                printf("Option invalid\n");
                return 1;
        }
    }
    printf("The set time is %s\n", argtime);
    return 0;
}

Here's some code I wrote to use getopt() to parse a command line switch, and argument. I want it argtime to default to "1970-01-01 00:00:00" if no argument is supplied, which it does, but when I use the -t switch and supply a different argument, argtime remains unaffected. So basically argtime = optarg; is not doing what it should, but I don't know why.

Upvotes: 0

Views: 173

Answers (2)

xing
xing

Reputation: 2446

You might use optind after the while to see if there is another argument and if so, use that argument instead of the default.

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

int main (int argc, char **argv) {
    //Initialise variable for switch option
    int option = 0;
    //Set time to default to epoch
    char *argtime = "1970-01-01 00:00:00";
    //Use getopt to parse switches t and h (neither requires an argument, as epoch is defaulted to if non is supplied)
    while ((option = getopt(argc, argv, "th")) != -1) {
        //Switch statements for supplied switches
        switch (option) {
            //If -t
            case 't':
                //If arg supplied
                printf("-t is selected.\n");
                break;
            //If -h
            case 'h':
                printf("Help is selected\n");
                break;
            //If anything else
            default:
                printf("Option invalid\n");
                return 1;
        }
    }
    if ( optind < argc) {//more arguments available
        //Set arg to given arg
        argtime = argv[optind];
    }

    printf("The set time is %s\n", argtime);
    return 0;
}

Upvotes: 0

John Bollinger
John Bollinger

Reputation: 180058

You need to tell getopt() about options that require an argument. As @xing described in comments, you do that by putting a colon in the option string, after the option letter that is affected. This allows getopt() to correctly handle grouped options and to recognize non-option arguments. Only if you do this can you expect option arguments to be communicated to you via optarg.

You claim in comments to want an optional option argument. POSIX-standard getopt() does not provide for that. In your particular case, it's not clear why you even want it, for what would it mean to specify a -t option without an argument? That the program should use a default? But that's what it will do if -t is omitted altogether.

Nevertheless, the way to approach the situation with POSIX getopt() is to provide two separate options, one that takes an argument and one that doesn't. For example, you might use option -T to signify whatever you wanted -t without an option to mean (getopt(argc, argv, "t:Th")). Alternatively, if you are willing to rely on GNU extensions then you can signify an optional option argument via a double colon (getopt(argc, argv, "t::h")), but this is less portable, and has slightly different semantics.

Upvotes: 1

Related Questions