getopt_long() — proper way to use it?

First off, you probably don’t want 0 for the has_arg field – it must be one of no_argumentrequired_arguemnt, or optional_argument. In your case, all of them are going to be required_argument. Besides that, you’re not using the flag field correctly – it has to be an integer pointer. If the corresponding flag is set, getopt_long() will fill it in with the integer you passed in via the val field. I don’t think you need this feature at all. Here’s a better (shortened) example for your case:

static struct option long_options[] =
{
    {"title", required_argument, NULL, 't'},
    {"artist", required_argument, NULL, 'a'},
    {NULL, 0, NULL, 0}
};

Then later, you can use it appropriately (straight from the manpage, I added some comments):

// loop over all of the options
while ((ch = getopt_long(argc, argv, "t:a:", long_options, NULL)) != -1)
{
    // check to see if a single character or long option came through
    switch (ch)
    {
         // short option 't'
         case 't':
             field.title = optarg; // or copy it if you want to
             break;
         // short option 'a'
         case 'a':
             field.artist = optarg; // or copy it if you want to
             break;
    }
}

You can extend for your other fields as necessary (and add some error handling, please!). Note – if you want to use -title and -artist like you have in your example, you’ll need to use getopt_long_only(), which doesn’t have short options.

As to your filename option, you’ll get that out as a '?' from the getopt_long() call, so you could handle it at that time. Your other options are to require that it is either the first or the last option and handle it by itself separately.

Leave a Comment