getopt C function

getopt C function

Post by Jeroen Valck » Fri, 08 Jun 2001 07:20:42



Hello,

I'm writing a little C program and I need to get the arguments passed on
the commandline.
So I thought about using the getopt function. It seems to work, but there
are some annoyances that I would like to solve. Maybe more experienced
programmers can help me out here. This is actually the first time that I
use getopt in a C program. So any help appreciated.
Also, getopt just gets the arguments. I need to check myself if for example
I want to make some arguments compulsory, right?
Below I included the example code and some test cases I'm wondering about.
Thanks.

#include <stdio.h>
#include <unistd.h>
#include <string.h>

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

        char
                        lca_directory[50],
                        lca_printer[50];
        int
                        liv_debug_mode = 0,
                        opt;

        /* initialization */
        strcpy(lca_directory, "");
        strcpy(lca_printer, "");

        while ((opt = getopt(argc, argv, "d:p:D")) != -1){
                switch(opt){
                case 'd':
                        strcpy(lca_directory, optarg);
                        break;
                case 'p':
                        strcpy(lca_printer, optarg);  
                case 'D':
                        liv_debug_mode = 1;
                        break;
                case ':':
                        fprintf(stderr, "option needs a value\n");
                        break;
                case '?':
                        /* getopt writes an err msg for unknow options */
                        /* just exit with err when unknow options are given */
                                /*  uncomment if you want to exit on an invalid option */
                        /* exit(1); */
                        break;
                }
        }

        /* check if directory is specified */
        if (strlen(lca_directory) == 0){
                fprintf(stderr, "Syntax Error: you must specify a directory\n");
                exit(1);
        }

        printf("directory: %s\n", lca_directory);
        printf("  printer: %s\n", lca_printer);
        printf("    debug: %d\n", liv_debug_mode);

        exit(0);

Quote:}

Now some tests.
1/
Tomsk:~/progs$ ./args -d directory -p printer -D
directory: directory
  printer: printer
    debug: 1
::::
No problem

2/
Tomsk:~/progs$ ./args -foo
./args: invalid option -- f
./args: invalid option -- o
./args: invalid option -- o
Syntax Error: you must specify a directory
::::
No problem

3/
Tomsk:~/progs$ ./args foo
Syntax Error: you must specify a directory
::::
Why isn't there an error message like above, invalid option.

4/
Tomsk:~/progs$ ./args -d -D
directory: -D
  printer:
    debug: 0
::::
This is not the behaviour I wished for!!!
-D is an option and is now processed as an argument for -d

--

ICQ# 30116911               Home page: http://www.valcke.com/jeroen
Phone +32(0)56 32 91 37     Mobile +32(0)486 88 21 26
Sleep is for the weak and sickly.

 
 
 

getopt C function

Post by Jan Schauma » Fri, 08 Jun 2001 08:06:13


[getopt]

Quote:>          while ((opt = getopt(argc, argv, "d:p:D")) != -1){
>                  switch(opt){

[snip]

Quote:>  Tomsk:~/progs$ ./args foo
>  Syntax Error: you must specify a directory
> ::::
>  Why isn't there an error message like above, invalid option.

Because you have not specified an option and getopt has not parsed
anything.  CL-Options start with "-" (or, if you use getopt_longopt,
"--something-long" or similar).

Therefor, you started your program with one argument, being "foo", which
was NOT a command-line option and as such was ignored by getopt.

Quote:>  Tomsk:~/progs$ ./args -d -D
>  directory: -D
>    printer:
>      debug: 0
> ::::
>  This is not the behaviour I wished for!!!
>  -D is an option and is now processed as an argument for -d

See above - you specify "d:" - this means that the comand-line option
"-d" MUST have an argument.  Therefore, getopt will assume whatever
follows the "-d" to be the argument passed to the "-d" option.

You will find that

./args -d

will give you an error saying that this option requires an argument.

Check the man-page for getopt (man 3 getopt) - it's exhaustive and gives
a few very good examples, covering all the basics.

HTH,
-Jan

--
Jan Schaumann
http://www.netmeister.org

 
 
 

getopt C function

Post by Ryan Younc » Fri, 08 Jun 2001 11:52:06



> 3/
> Tomsk:~/progs$ ./args foo
> Syntax Error: you must specify a directory
> ::::
> Why isn't there an error message like above, invalid option.

getopt will return -1 when it exhausts all options on the command line.  In
this case, there were no options passed, just an argument.  As such, getopt
returned -1 at its first call.

Quote:> 4/
> Tomsk:~/progs$ ./args -d -D
> directory: -D
>   printer:
>     debug: 0
> ::::
> This is not the behaviour I wished for!!!
> -D is an option and is now processed as an argument for -d

The optstring specification passed to getopt is strict in that if you specify
an option takes an argument, the option _will_ take an argument, even if the
argument looks like an option.  If you really want to get by this, parse
the command line yourself, or investigate using some means of checking
on optarg afterwards and using optreset if available (detailed in the man
page if it is).

--

"B can be thought of as C without types; more accurately, it is BCPL squeezed
 into 8K bytes of memory and filtered through Thompson's brain."
                  --Dennis Ritchie, "The Development of the C Language", 1993