Linux: linux getopt_long() function (command line parsing) (getopt, getopt_long_only) (short option -, long option –)

Foreword

In Linux, various commands are often needed, usually with various parameters. How are these parameters parsed? Usually the functions getopt, getopt_long, and getopt_long_only functions provided by GNU C are used to parse command line parameters.

1. About command line parameters

Command line parameters can be divided into two categories, one is short options, and the other is long options. Short options are preceded by a dash “-“, and long options are preceded by two dashes “–”. As shown in the following table (ls command parameters), -a, -A, and -b all represent short options, and –all, –almost-all, and –author all represent long options. Both of them can optionally be followed by additional parameters. For example –block-size=SIZE, SIZE is an additional parameter. For example:

LS(1) User Commands LS(1)

NAME
ls-list directory contents

SYNOPSIS
ls [OPTION]… [FILE]…

DESCRIPTION
List information about the FILEs (the current directory by default).
Sort entries alphabetically if none of -cftuvSUX nor –sort is speci‐
fielded.

Mandatory arguments to long options are mandatory for short options
too.

-a, –all
do not ignore entries starting with .

-A, –almost-all
do not list implied . and ..

–author
with -l, print the author of each file

-b, –escape
print C-style escapes for nongraphic characters

–block-size=SIZE
scale sizes by SIZE before printing them; e.g., ‘–block-size=M’
prints sizes in units of 1,048,576 bytes; see SIZE format below

-B, –ignore-backups
do not list implied entries ending with ~

2. getopt_long function

The getopt function can only handle short options, while the getopt_long function can handle both. It can be said that getopt_long already contains the functions of getopt. Therefore, only the getopt_long function is introduced here. The difference between getopt_long and getopt_long_only is very small. It will be better to mention getopt_long after introducing getopt_long.

#include
extern char *optarg;
extern int optind, opterr, optopt;
#include
int getopt(int argc, char * const argv[], const char *optstring);
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);
int getopt_long_only(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);

Introduction to parameters and return values (applicable to the above three functions):
1. argc and argv are the same as the two parameters of the main function.
2. optstring: represents a short option string.

The form is like “a:b::cd:”, which respectively indicates that the command line short options supported by the program are -a, -b, -c, and -d. The meaning of the colon is as follows:
(1) Only one character, without colon – only represents options, such as -c
(2) One character, followed by a colon – indicating that the option is followed by a parameter, such as -a 100
(3) One character, followed by two colons – indicates that the option is followed by an optional parameter, that is, the parameter is optional. If there is a parameter, there cannot be a space between the option and the parameter.
The form should be like -b200

3. longopts: represents the long option structure. The structure is as follows:

struct option
{
const char *name;
int has_arg;
int *flag;
int val;
};
eg:
static struct option longOpts[] = {
{ “daemon”, no_argument, NULL, ‘D’ },
{ “dir”, required_argument, NULL, ‘d’ },
{ “out”, required_argument, NULL, ‘o’ },
{ “log”, required_argument, NULL, ‘l’ },
{ “split”, required_argument, NULL, ‘s’ },
{ “http-proxy”, required_argument, &lopt, 1 },
{ “http-user”, required_argument, &lopt, 2 },
{ “http-passwd”, required_argument, &lopt, 3 },
{ “http-proxy-user”, required_argument, & amp;lopt, 4 },
{ “http-proxy-passwd”, required_argument, &lopt, 5 },
{ “http-auth-scheme”, required_argument, &lopt, 6 },
{ “version”, no_argument, NULL, ‘v’ },
{ “help”, no_argument, NULL, ‘h’ },
{ 0, 0, 0, 0 }
};

(1)name: indicates the name of the option, such as daemon, dir, out, etc.

(2)has_arg: Indicates whether the option carries parameters. This parameter has three different values, as follows:

a: no_argument (or 0) – the parameter is not followed by the parameter value, eg: –version, –help
When b: required_argument (or 1) – the parameter input format is: –parameter value or –parameter=value. eg:–dir=/home
c: optional_argument (or 2) – the parameter input format can only be: –parameter=value

(3)flag: This parameter has two meanings, empty or non-empty.

a: If the parameter is NULL, getopt_long will return the val value when a long option is selected.
eg, executable program –help, the return value of getopt_long is h.
b: If the parameter is not empty, then when a long option is selected, getopt_long will return 0 and point the flag pointer parameter to the val value.
eg: executable program –http-proxy=127.0.0.1:80 then getopt_long return value is 0, and lopt value is 1.

(4) val: Indicates the return value when the specified function finds the option, or the value val of the data pointed to by the specified flag when the flag is not empty.

4. Longindex: longindex is not empty. The variable it points to will record the description of which element in longopts the currently found parameter matches, which is the subscript value of longopts.
5. Global variables:

(1) optarg: Indicates the parameter value corresponding to the current option.

(2) optind: represents the subscript value in argv of the next parameter to be processed.

(3) opterr: If opterr = 0, error information will not be output to the standard output stream when an error is encountered in getopt, getopt_long, and getopt_long_only. When opterr is non-zero, an error is output to the screen.

(4) optopt: Indicates that there are no unidentified options.

6. Return value:

(1) If the short option is found, the characters corresponding to the short option will be returned.

(2) If the long option is found, if flag is NULL, return val. If flag is not empty, return 0

(3) If you encounter an option that is not in short characters or long characters. Or if there is ambiguity in the long characters, “?” will be returned.

(4) If all characters are not found after parsing (usually the input command parameter format is wrong, eg: there is no option to add a slash), return “-1”

(5) If the option requires parameters, forget to add the parameters. The return value depends on optstring, if its first character is “:”, then “:” is returned, otherwise “?” is returned.

Notice:

(1) The last element of longopts must be filled with all 0s, otherwise a segmentation error will be reported

(2) Each option in the short option is unique. If the long option is abbreviated, it also needs to be unique.

3. Test (self-test) (getopts has two implicit variables when operating with case: one is OPTARG, which is used to take the value of the current option, and the other is OPTIND, which represents the position of the next element to be processed. .)

1. The official website provides test cases.

#include <stdio.h> /* for printf */
#include <stdlib.h> /* for exit */
#include <getopt.h>
 
int main(int argc, char **argv)
{
    int c;
    int digit_optind = 0;
 
   while (1) {
        int this_option_optind = optind ? optind : 1;
        int option_index = 0;
        static struct option long_options[] = {
            {"add", required_argument, 0, 0 },
            {"append", no_argument, 0, 0 },
            {"delete", required_argument, 0, 0 },
            {"verbose", no_argument, 0, 0 },
            {"create", required_argument, 0, 'c'},
            {"file", required_argument, 0, 0 },
            {0, 0, 0, 0}
        };
 
       c = getopt_long(argc, argv, "abc:d:012",
                 long_options, & amp;option_index);
        if (c == -1)
            break;
 
       switch (c) {
        case 0:
            printf("option %s", long_options[option_index].name);
            if(optarg)
                printf(" with arg %s", optarg);
            printf("\\
");
            break;
 
       case '0':
       case '1':
       case '2':
            if (digit_optind != 0 & amp; & amp; digit_optind != this_option_optind)
              printf("digits occur in two different argv-elements.\\
");
            digit_optind = this_option_optind;
            printf("option %c\\
", c);
            break;
 
       case 'a':
            printf("option a\\
");
            break;
 
       case 'b':
            printf("option b\\
");
            break;
 
       case 'c':
            printf("option c with value '%s'\\
", optarg);
            break;
 
       case 'd':
            printf("option d with value '%s'\\
", optarg);
            break;
 
       case '?':
            break;
 
       default:
            printf(" getopt returned character code 0%o \\
", c);
        }
    }
 
   if (optind < argc) {
        printf("non-option ARGV-elements: ");
        while (optind < argc)
            printf("%s ", argv[optind + + ]);
        printf("\\
");
    }
 
   exit(EXIT_SUCCESS);
}

operation result:

[root@ubuntu /home/yg/arnold_test/20211129_TEST_getopt]23# ./a.out -0
option 0
[root@ubuntu /home/yg/arnold_test/20211129_TEST_getopt]24# ./a.out -1
option 1
[root@ubuntu /home/yg/arnold_test/20211129_TEST_getopt]25# ./a.out -2
option 2
[root@ubuntu /home/yg/arnold_test/20211129_TEST_getopt]26# ./a.out -a
option a
[root@ubuntu /home/yg/arnold_test/20211129_TEST_getopt]27# ./a.out -b
option b
[root@ubuntu /home/yg/arnold_test/20211129_TEST_getopt]28#
[root@ubuntu /home/yg/arnold_test/20211129_TEST_getopt]28# ./a.out -c100
option c with value ‘100’
[root@ubuntu /home/yg/arnold_test/20211129_TEST_getopt]29# ./a.out -d333
option d with value ‘333’

refer to

Example of Parsing Long Options with getopt_long

The knowledge points of the article match the official knowledge files, and you can further learn related knowledge. C Skill Tree Home Page Overview 194641 people are learning the system

syntaxbug.com © 2021 All Rights Reserved.