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

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值