View Single Post
  #2   (View Single Post)  
Old 14th March 2013
ocicat ocicat is offline
Administrator
 
Join Date: Apr 2008
Posts: 3,319
Default

Quote:
Originally Posted by bsdplus View Post
after arguments are processed in the while loop, there are two lines:

Code:
           argc -= optind;
           argv += optind;
Could somebody help explain the purpose of these two lines?
Adjusting argc & argv is optional. However, the value of optind (which contains the number of arguments which have conformed to the expectations of getopt(3)...) can be used to filter out what has already been processed from those arguments which have yet to be processed.

The following modification to the code found in the getopt(3) manpage illustrates the intended use. Note that all options intended to be processed by getopt(3) must precede those arguments not to be processed by getopt(3):
Code:
$ cat main.c
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
  int bflag, ch;

  printf("processing any options provided:\n");

  bflag = 0;
  while ((ch = getopt(argc, argv, "bf:")) != -1) {
    switch (ch) {
    case 'b':
      printf("processing option '-b'\n");
      bflag = 1;
      break;
    case 'f':
      printf("processing option '-f'\n");
      printf("optarg = '%s'\n", optarg);
      break;
    default:
      printf("default\n");
    }
  }

  printf("after processing options:\n");

  printf("bflag = %d\n", bflag);
  printf("optind = %d\n", optind);
  printf("argc = %d\n", argc);
  printf("argv = %s\n", *argv);

  argc -= optind;
  argv += optind;

  printf("after adjusting argc and argv:\n");

  printf("argc = %d\n", argc);
  printf("argv = %s\n", *argv);

  return 0;
}
$ gcc main.c
$ ./a.out -f foobar -b xyzzy
processing any options provided:
processing option '-f'
optarg = 'foobar'
processing option '-b'
after processing options:
bflag = 1
optind = 4
argc = 5
argv = ./a.out
after adjusting argc and argv:
argc = 1
argv = xyzzy
$
By adjusting argc & argv after processing the entire argument list, one argument (xyzzy) remains which did not conform to getopt(3)'s intended behaviour. This argument can now be processed later in the code without the programmer needing to take into account all of the getopt(3) processing.

Again, one does not have to change argc or argv. optind merely provides information which can be exploited or ignored.
Quote:
I played with the example code in getopt man page, "argc -= optind" seems to set argc to 0.
This is correct if you only provided command-line options which were completely consumed by getopt(3)'s processing. If the entire list of command-line arguments is processed by getopt(3), then argc & argv will indicate that no other command-line arguments are yet to be processed in some manner. Note that in my example, one more command-line argument is not processed. Adjusting argc & argv might simplify accessing any arguments still to be read, but it is up to the programmer to deal with these command-line arguments as he/she decides is warranted.

Last edited by ocicat; 15th March 2013 at 12:05 AM. Reason: add clarity
Reply With Quote