DaemonForums  

Go Back   DaemonForums > Miscellaneous > Programming

Programming C, bash, Python, Perl, PHP, Java, you name it.

Reply
 
Thread Tools Display Modes
  #1   (View Single Post)  
Old 14th March 2013
bsdplus bsdplus is offline
Real Name: Alan Cheng
Port Guard
 
Join Date: Jun 2009
Location: Shanghai, China
Posts: 21
Thanked 0 Times in 0 Posts
Default Question on getopt and optind

Hello,


In getopt(3) man page, 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?

I played with the example code in getopt man page, "argc -= optind" seems to set argc to 0.
I also understand that "argv += optind" make the argv pointer pass over current argument string. But just could not figure out why we need to do that.

Thanks.

example code in getopt (3) man page:
Code:
           int bflag, ch, fd;

           bflag = 0;
           while ((ch = getopt(argc, argv, "bf:")) != -1) {
                   switch (ch) {
                   case 'b':
                           bflag = 1;
                           break;
                   case 'f':
                           if ((fd = open(optarg, O_RDONLY, 0)) == -1)
                                   err(1, "%s", optarg);
                           break;
                   default:
                           usage();
                           /* NOTREACHED */
                   }
           }
           argc -= optind;
           argv += optind;
Reply With Quote
  #2   (View Single Post)  
Old 14th March 2013
ocicat ocicat is offline
Administrator
 
Join Date: Apr 2008
Posts: 2,876
Thanked 190 Times in 160 Posts
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
  #3   (View Single Post)  
Old 26th March 2013
bsdplus bsdplus is offline
Real Name: Alan Cheng
Port Guard
 
Join Date: Jun 2009
Location: Shanghai, China
Posts: 21
Thanked 0 Times in 0 Posts
Default

with getopt, I thought all arguments passed on on command line have to be processed by it and it would be treated as error if more arguments are passed than it would expect.

Things are now a lot more clear. Thanks ocicat for the explanation and example.

Last edited by bsdplus; 26th March 2013 at 11:19 AM. Reason: fix typos
Reply With Quote
  #4   (View Single Post)  
Old 26th March 2013
ocicat ocicat is offline
Administrator
 
Join Date: Apr 2008
Posts: 2,876
Thanked 190 Times in 160 Posts
Default

Quote:
Originally Posted by bsdplus View Post
with getopt, I thought all arguments passed on on command line have to be processed by it and it would be treated as error if more arguments are passed than it would expect.
getopt(3) will only process what it is instructed to interpret.

Recognize that the example I provided is limited in the way that optind was used. Here, all command-line parameters understood by getopt(3) had to be provided first. This is not a limitation by getopt(3) itself; it is merely a limitation imposed by how optind was being used to distinguish which parameters were not processed by getopt(3). A more complicated scheme could be implemented which would allow any kind of ordering, but that would be more involved than a twenty line example.
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
ports version of getopt fridder FreeBSD Ports and Packages 0 8th July 2011 06:19 PM
PF question bug0r OpenBSD Security 7 23rd November 2009 03:54 PM
external drive partition question + fdisk question gosha OpenBSD General 15 15th June 2009 02:00 PM
DR-DOS question RJPugh Other OS 4 31st May 2009 11:10 AM
Question about DNS. bigb89 FreeBSD General 10 22nd May 2008 06:08 AM


All times are GMT. The time now is 01:54 PM.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick