Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getopt_long() -- proper way to use it?

Tags:

c

OK, I have searched and found the following two StackOverflow topics that started me in the right direction:

Argument-parsing helpers for C/UNIX

Pass arguments into C program from command line

NOTE: ALL CODE IS PSEUDO-CODE. WILL POST COMPILABLE CODE WHEN IT WORKS.

However, I'm still completely confused on how to use getopt_long() in C. The program I'm writing is defined as having the following possible tags (but can include as many as you absolutely need, filling the rest in with empty values):

id3tagEd filename -title "title" -artist "artist" -year 1991 -comment "comment" -album "album" -track 1 

Now, from what I read, I need to utilize a struct for the long options, correct? If so, I wrote something along the lines of this:

struct fields field = {     char *[] title;     char *[] artist;     char *[] album;     int year;     char *[] comment;     int track; }   static struct options long_options[] = {     {"title", 0, &field.title, 't'},     {"artist", 0, &field.artist, 'a'},     {"album", 0, &field.album, 'b'},     {"year", 0, &field.year, 'y'},     {"comment", 0, &field.comment, 'c'},     {"track", 0, &field.track, 'u'},     {0, 0, 0, 0} } 

Now, from what I gathered, I would be calling it via this:

int option_index = 0;  int values = getopt_long(argc, argv, "tabycu", long_options, &option_index); 

From here, could I strictly use the field struct and do what I need to within my program? However, if this is the case, can someone explain the whole long_options struct? I read the man pages and such, and I'm just utterly confused. By rereading the man pages, I can see I can set variables to null, and should be setting all my option requirements to "required_argument"? And then setting the structs via a while() loop? However, I see optarg being used. Is this set by getopt_long()? Or is it missing from the example?

And one last issue, I will always have an unnamed required option: filename, would I just use argv[0] to gain access to that? (Since I can assume it'll be first).

On a side note, this is related to a homework problem, but it has nothing to do with fixing it, its more of a fundamental, have to understand argument passing and parsing in C via command line first.

like image 443
Jeremy Dentel Avatar asked Sep 20 '11 17:09

Jeremy Dentel


1 Answers

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.

like image 128
Carl Norum Avatar answered Oct 06 '22 17:10

Carl Norum