First off, you probably don’t want 0 for the has_arg field – it must be one of no_argument, required_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.