Thread: Need help with getopt_long function.

  1. #1
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96

    Need help with getopt_long function.

    Hello,

    I'm writing a program. I'd like it to be compatible with MinGW's C compiler and Linux. Right now, I'm writing the code in Linux. I'm not 100% sure MinGW has the getopt_long function or if it's just a *nix thing. Anyway, I'm having some trouble understanding this code. I've a read a bit about this but I'm still a bit confused and was hoping someone here could help. I'll post the code and then ask my question.

    Code:
    int do_all, do_help, do_verbose;    /* flag variables */
    char *myfile, *user;                /* input file, user name */
    
    struct option longopts[] = {
       { "all",     no_argument,       & do_all,     1   },
       { "file",    required_argument, NULL,         'f' },
       { "help",    no_argument,       & do_help,    1   },
       { "verbose", no_argument,       & do_verbose, 1   },
       { "user"   , optional_argument, NULL,         'u' },
       { 0, 0, 0, 0 }
    };
    ...
    while ((c = getopt_long(argc, argv, ":ahvf:u::W;", longopts, NULL)) != –1) {
        switch (c) {
        case 'a':
            do_all = 1;
            break;
        case 'f':
            myfile = optarg;
            break;
        case 'h':
            do_help = 1;
            break;
        case 'u':
            if (optarg != NULL)
               user = optarg;
            else
               user = "root";
            break;
        case 'v':
            do_verbose = 1;
            break;
        case 0:     /* getopt_long() set a variable, just keep going */
            break;
    #if 0
        case 1:
            /*
             * Use this case if getopt_long() should go through all
             * arguments. If so, add a leading '-' character to optstring.
             * Actual code, if any, goes here.
             */
            break;
    #endif
        case ':':   /* missing option argument */
            fprintf(stderr, "%s: option `-%c' requires an argument\n",
                    argv[0], optopt);
            break;
        case '?':
        default:    /* invalid option */
            fprintf(stderr, "%s: option `-%c' is invalid: ignored\n",
                    argv[0], optopt);
            break;
        }
    }
    I don't really understand the val field in the struct option longopts part.
    Code:
    struct option longopts[] = {
       { "all",     no_argument,       & do_all,     1   },
       { "file",    required_argument, NULL,         'f' },
       { "help",    no_argument,       & do_help,    1   },
       { "verbose", no_argument,       & do_verbose, 1   },
       { "user"   , optional_argument, NULL,         'u' },
       { 0, 0, 0, 0 }
    };
    My understanding is the third element determines what happens with the fourth element there. So, if I pass --all to my program, getopt_long will return 1. Is that the whole point of the case 0: and the case 1: at the bottom of the case / switch statement?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well the short answer would be to add a few more debug printf statements, and just run the code to observe what it does.

    Then if you're confused about what the 'val' field does, you can change a 1 to a 2, and observe what happens. Through experimentation and observation, you learn.

    Yes we could explain, but how would that be any better than what the manual page already says?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    Quote Originally Posted by Salem View Post
    Well the short answer would be to add a few more debug printf statements, and just run the code to observe what it does.

    Then if you're confused about what the 'val' field does, you can change a 1 to a 2, and observe what happens. Through experimentation and observation, you learn.

    Yes we could explain, but how would that be any better than what the manual page already says?
    Thank you for the reply Salem. I have been trying to experiment with the getopt_long function and I have been using printf / fprintf statements to try and figure out what the flag variable does, but I needed more information. In the above example, let's say I pass the --help switch on the command line to my program. Does 1 get stored in do_help? If so, what's the point of setting do_help to one in the case statement? My understanding, from reading the man page, if flag is not NULL, then val gets stored in the variable that flag points to. I had tried using printf statements to figure this out. This is what I actually have:

    Code:
        while ((c = getopt_long(argc, argv, ":ahvf:u::W;", longopts, NULL)) != -1) {
            if(do_all==1) {
               printf("all.\n");
            }
     
            if(do_help==1) {
              printf("help.\n");
            }
    
    
            if(do_verbose==1) {
              printf("verbose.\n");
            }
            switch (c) {
    /* the rest of the code... */
    If pass the --all switch, ./getopt_long --all, "help" and "all" get printed to stdout. If I pass the --help switch, ./getopt_long --help, just "help" gets displayed on the screen. If I pass the --verbose switch, ./getopt_long --verbose, "help" and "verbose" get printed to stdout. I'll change the val to 2 on some of them, but I don't think that's going to help me figure out what I'm doing wrong here. Thanks for trying to help.

  4. #4
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    I am so stupid. I forgot to initialize the integers to 0. So when I was testing the values of the various integers, some were coming back as being set. So, another question though. In the man page example if the --verbose switch, for example, is passed to my program, getopt_long sets the value of do_verbose to one. How come in the switch / case statement, they're setting do_verbose, if it's already being set by getopt_long?

  5. #5
    Registered User
    Join Date
    Jun 2015
    Posts
    1,640
    Quote Originally Posted by Spork Schivago View Post
    In the man page example if the --verbose switch, for example, is passed to my program, getopt_long sets the value of do_verbose to one. How come in the switch / case statement, they're setting do_verbose, if it's already being set by getopt_long?
    The case statement sets it for the short option since the *flag=value mechanism only works for long options.

    For long options that also have short versions it makes more sense to set flag to NULL and set value to the short option letter so you can handle everything in one place.

  6. #6
    Registered User
    Join Date
    Mar 2014
    Location
    Corning, New York, USA
    Posts
    96
    Quote Originally Posted by algorism View Post
    The case statement sets it for the short option since the *flag=value mechanism only works for long options.

    For long options that also have short versions it makes more sense to set flag to NULL and set value to the short option letter so you can handle everything in one place.
    Thank you! That's what I was missing. Much appreciated!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault - getopt_long()
    By capslocktrojan in forum Linux Programming
    Replies: 7
    Last Post: 10-25-2014, 09:36 AM
  2. getopt_long unrecognized option
    By ShereModulus in forum C Programming
    Replies: 1
    Last Post: 08-19-2012, 09:56 PM
  3. getopt_long
    By SeriousTyro in forum C Programming
    Replies: 2
    Last Post: 10-31-2010, 03:46 PM
  4. getopt_long
    By ear in forum C Programming
    Replies: 6
    Last Post: 06-12-2007, 02:52 PM
  5. understanding getopt_long()
    By kristy in forum C Programming
    Replies: 0
    Last Post: 01-03-2004, 06:58 AM