Command Line Options: getopt_long() Learning Note

Definition

 

#include <getopt .h>

extern char *optarg

extern int optind , opterr , optopt ;

int getopt_long (int argc , char * const argv [],
                  const char *optstring ,
                  const struct option *longopts , int *longindex );

 

optarg : if an option takes an argument, the pointer will point at that argument.

 

optind : is the index of the next element to be processed in argv .
The system initializes this value to 1 .  The caller can reset it to 1 to restart scanning of the same argv, or when scanning a new argument vector.

 

After all command-line options have been parsed, the optind value could be equal to argc or less than argc . If optind < argc, means there are verbose arguments left which cannot be parse by getopt ().

 

opterr, optopt : If getopt () does not recognize an option character, it prints an error message to stderr , stores the character in optopt , and returns '? '. The calling program may prevent the error message by setting opterr to 0 .

 

Parameters

 

argc : the count of input parameters, which passed to the main() function on program invocation.

 

argv : the array of input parameters, which passed to the main() function on program invocation.

 

optstring : a character string containing the valid short options, each a single letter. An option that requires an argument is followed by a colon. For your program, the string ho:v indicates that
the valid options are -h, -o, and -v, with the second of these options followed by an argument.

 

       if a character is followed by a colon, means the option requires an argument.

       For example: ho:v    , means option o requires an argument, used as: "-o arg ".

 

       if a character is followed by two colons, means the option takes an optional argument.

       For example: ho::v    , means option o takes an optional argument, used as: "-oarg ", or "-o ".

       we should notice that if we use "-o arg " under the circumstances, "arg " will not be parsed as 

       the argument of option "o ".

 

longopts : a pointer to the first element of an array of struct option declared in <getopt.h > as

       struct option {
               const char *name;
               int         has_arg;
               int        *flag;
               int         val;
           };

       The meanings of the different fields are:

       name   is the name of the long option.

       has_arg

              is:

              no_argument (or 0) if the option does not take an argument;
              required_argument (or 1) if the option requires an argument;
              optional_argument (or 2) if the option takes an optional argument.

       flag    specifies how results are returned for a long option.  If flag is NULL ,
              then getopt_long() returns val.  (For example, the calling program may
              set val to the equivalent short option character.)  Otherwise,
              getopt_long() returns 0, and flag points to a variable which is set to
              val if the option is found, but left unchanged if the option is not
              found.

       val    is the value to return, or to load into the variable pointed to by
              flag.

 

longindex : If it is not NULL , it points to a variable which is set to the index of the long option relative to longopts .

 

 

Return Value

 

If an option was successfully found, then getopt() returns the option character. If all command-line options have been parsed, then getopt() returns -1 .  If getopt() encounters an option character that was not in optstring, then '?' is returned.  If getopt() encounters an option with a missing argument, then the return value depends on the first character in optstring: if it is ':', then ':' is returned; otherwise '?' is returned.

 

After all command-line options have been parsed, the optind value could be equal to argc or less than argc . If optind < argc, means there are verbose arguments left which cannot be parse by getopt (). Under the circumstances, these verbose arguments can be feached from the changed(by getopt() ) array argv from argv[ind] to argv[argc-1] .

 

 

Sample Code

 

NOTE: the following code is written under the stardard of C99, use blow command to compile:

[280047@SHNI145 code] $ gcc -Wall -std=gnu99 -g getopt.c -o getopt

 

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>

/* The name of this program. */
const char* program_name;

/* Prints usage information for this program to STREAM (typically stdout or stderr),
 * and exit program with EXIT_CODE. Does not return. */
void print_usage(FILE* stream, const int exit_code, const char* error_message) {
    if(error_message != NULL) {
        fprintf(stream, "%s \n", error_message);
    }
    fprintf(stream, "Usage: %s options [inputfile ...]\n", program_name);
    fprintf(stream, 
            "   -h         --help              Display this usage information. \n"
            "   -f <file>  --output filename   Write output to file. \n"
            "   -o<Arg>    --optional          Print optional argument. \n");
    exit(exit_code);
}

void print_argument(const int option, const char* argument) {
    if(argument != NULL) {
        printf("%c == %s \n", option, argument);
    }
}

void print_verbose_arguments(const int argc, char* const* argv) {    
    for(int i=optind; i<argc; i++) {
        printf("verbose argument: %s\n", argv[i]);
    }    
}

void reset_optind(void)
{
    optind = 1;
}

void parse_parameters(const int argc, char* const* argv, const char* const optstring, const struct option* longopts) {    
    int next_option = 0;
    if(argc <= 1) {
        print_usage(stdout, 0, NULL);
    } else {    
        reset_optind();
        while(next_option = getopt_long(argc, argv, optstring, longopts, NULL), next_option != -1) {
            if(next_option == 'h') {
                print_usage(stdout, 0, NULL);
            } else if(next_option == 'f') {
                print_argument(next_option, optarg);
            } else if(next_option == 'o') {
                print_argument(next_option, optarg);
            } else if(next_option == '?') {
                print_usage(stderr, 1, NULL);
            } 
        } 
        print_verbose_arguments(argc, argv);
    }

}

int main(int argc, char** argv)
{
    /* A string listing valid short options letters. */
    const char* const short_options = "hf:o::";
    /* An array descriping valid long options. */
    const struct option long_options[] =    {
        { .name="help",     .has_arg=no_argument,           .flag=NULL,   .val='h' },
        { .name="output",   .has_arg=required_argument,     .flag=NULL,   .val='f' },
        { .name="option",   .has_arg=optional_argument,     .flag=NULL,   .val='o' },
        { .name=NULL,       .has_arg=no_argument,           .flag=NULL,   .val=0   }   };    
    /* Remember the name of the program, to incorporate in messages.
     * The name is stored in argv[0]. */
    program_name = argv[0];

    parse_parameters(argc, argv, short_options, long_options);

    return 0;
}


 

Test

 

[280047@SHNI145 code] $ ./getopt -h
Usage: ./getopt options [inputfile ...]
   -h         --help              Display this usage information.
   -f <file>  --output filename   Write output to file.
   -o<Arg>    --optional          Print optional argument.

[280047@SHNI145 code] $ ./getopt -f file
f == file

[280047@SHNI145 code] $ ./getopt -oArg
o == Arg

[280047@SHNI145 code] $ ./getopt -o arg
verbose argument: arg

[280047@SHNI145 code] $ ./getopt 11 22 33 44 -f 55 -o 66
f == 55
verbose argument: 11
verbose argument: 22
verbose argument: 33
verbose argument: 44
verbose argument: 66

[280047@SHNI145 code] $ ./getopt -f 11 22 33 44 -f 55 -o 66
f == 11
f == 55
verbose argument: 22
verbose argument: 33
verbose argument: 44
verbose argument: 66

[280047@SHNI145 code] $ ./getopt --output 11 22 33 44 -option=55 -o 66
f == 11
o == ption=55
verbose argument: 22
verbose argument: 33
verbose argument: 44
verbose argument: 66

[280047@SHNI145 code] $ ./getopt --output=11 22 33 44 --option=55 -o 66
f == 11
o == 55
verbose argument: 22
verbose argument: 33
verbose argument: 44
verbose argument: 66

 

 

reference

 

Advance Linux Programming

http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html

 

 

 

 

 

你可能感兴趣的:(c,linux,gcc,getopt,getopt_long)