Command Line Parameter Parsing: getopt () and getopt_long ()

Source: Internet
Author: User
Tags arabic numbers posix

In Linux, many programs, even those with graphical user interfaces (guis), can accept and process command line options. For some programs, this is the main means to interact with other programs or users. With a reliable and complex command line parameter processing mechanism, your applications will be better and more useful. However, many developers spend their precious time writing their own command line Resolvers without using getopt (), the latter is a library function specifically designed to reduce the burden on command line processing.

1. Command Line Parameters
The primary task of the command line program design is to parse the command line parameters, which is seldom concerned by GUI programmers. Here, we use a popular definition of the parameter (argument): strings on the command line except the command name. Parameters are composed of multiple items. items and items are separated by blank spaces.
Parameters are further divided into options and operands. Option is used to modify the default behavior of a program or provide information for the program. The old Convention begins with a dash. Options can follow some parameters, called option parameters. The rest is the operand.
2. POSIX conventions POSIX indicates portable operating system interfaces: portable operating system interfaces, the Institute of Electrical and Electronics Engineers (IEEE) initially developed POSIX standards, to improve the portability of applications in UNIX environments. However, POSIX is not limited to Unix. Many other operating systems, such as DEC OpenVMS and Microsoft Windows NT, support the POSIX standard.

The following are the conventions on program names and parameters in POSIX:
The program name should not be less than 2 Characters and no more than 9 characters;
The program name should only contain lowercase letters and Arabic numbers;
The option name should be a single-character active single-digit, with a short horizontal '-' as the front digit;
You can merge multiple options that do not require option parameters. (For example, foo-a-B-c ----> foo-ABC)
Options and their parameters are separated by a blank space character;
Optional.
If the option parameter has multiple values, it must be passed in without a string. For example, myprog-U "Arnold, Joe, Jane ". In this case, you need to solve the separation problem of these parameters by yourself.
The option should appear before the operand appears.
The special parameter '--' indicates that all parameters are completed, and any subsequent parameter is considered as the operand.
There is no relationship between options, but they are mutually exclusive. If the operation result of one option overwrites the operation result of other options, the last option takes effect. If the option is repeated, it is processed sequentially.
The sequence of allowed operands affects program behavior, but it must be documented.
The program that reads and writes a specified file should treat a single parameter '-' as a meaningful standard input or output.
Of course, many standards do not comply with the above conventions, mainly due to historical compatibility issues, because before the emergence of the standard, there have been more than n programs.
3. GNU Long Options
GNU encourages programmers to use long options in the form of -- help and -- verbose. These options do not conflict with POSIX conventions, but are easy to remember. They also provide the opportunity to maintain consistency among all GNU tools. The GNU long option has its own conventions:
For GNU programs that have followed the POSIX conventions, each short option has a corresponding long option.
Additional Long Options for GNU do not need the corresponding short options. We recommend that you have them.
The length option can be abbreviated as a string with the minimum uniqueness.
The option parameter and the long option are separated by a '=' or by a blank character.
The option parameter is optional (only valid for the short option ).
The length option can be prefixed with a dash.
4. Basic command line Processing Technology

The C program accesses its command line parameters through the argc and argv parameters. Argc is an integer that represents the number of parameters (including the command name ). The main () function can be defined in two ways. The difference lies only in how argv is defined: int main (INT argc, char * argv [])
{
......
} Int main (INT argc, char ** argv)
{
......
}

When the C Runtime Library program starts code to call your main (), the command line has been processed. The argc parameter contains the Count value of the parameter, and argv contains an array of pointers to these parameters. Argv [0] is the program name.

An example of a simple command line processing technique is the Echo program, which can output parameters to standard devices, separate them with space characters, and finally wrap the lines. If the first parameter of the command line is-N, the line breaks.
Listing 1: # include <stdio. h>

Int main (INT argc, char ** argv)
{
Int I, nflg;

Nflg = 0;
If (argc> 1 & argv [1] [0] = '-' & argv [1] [1] = 'n '){
Nflg ++;
Argc --;
Argv ++;
}
For (I = 1; I <argc; I ++ ){
Fputs (argv [I], stdout );
If (I <argc-1)
Putchar ('');
}
If (nflg = 0)
Putchar ('/N ');

Return 0;
}

In the code above, the highlighted area is carefully studied and it will be interesting.

In the Echo program, the parsing of command line parameters is manually implemented. A long time ago, the Unix Support Team developed the getopt () function to simplify the parsing of command line parameters and provided several external variables, making it easier to write POSIX-compliant code.
5. Command Line Parameter Parsing function -- getopt ()

The getopt () function declaration is as follows: # include <unistd. h>

Int getopt (INT argc, char * const argv [], const char * optstring );

Extern char * optarg;
Extern int optind, opterr, optopt;

The argc and argv parameters of this function are usually directly transmitted from the main () parameters. Optstring is a string consisting of option letters. If any character in the string is followed by a colon, this option requires an option parameter.

Given the number of getopt () command parameters (argc), the array pointing to these parameters (argv), and the option string (optstring), getopt () returns the first option, and set some global variables. When you call this function again with the same parameters, it returns the next option and sets the corresponding global variable. If no recognizable option is available,-1 is returned, and the task is completed.

The global variables set by getopt () include:
Char * optarg -- string of the current option parameter (if any ).
Int optind -- the current index value of argv. When getopt () is used in a while loop, after the loop ends, the remaining strings are treated as operands, which can be found in argv [optind] To argv [argc-1.
Int opterr -- if this variable is not zero, the getopt () function is "invalid option" and "Parameter options are missing, and the error message is output.
Int optopt -- if an invalid option character is found, the getopt () function or '? 'Character, or return ':' character, and optopt contains the found invalid option characters.

The following describes how to use getopt () to write a small program.

Program description:

Program name: opt_parse_demo

Option:
-N -- display my name.
-G -- display my girlfriend's name.
-L -- options with parameters.
Listing 2: # include <stdio. h>
# Include <unistd. h>

Int main (INT argc, char ** argv)
{
Int OC;/* option character */
Char * B _opt_arg;/* option parameter string */

While (OC = getopt (argc, argv, "NGL :"))! =-1)
{
Switch (OC)
{
Case 'N ':
Printf ("My name is lyong./N ");
Break;
Case 'G ':
Printf ("Her name is xxiong./N ");
Break;
Case 'l ':
B _opt_arg = optarg;
Printf ("Our love is % s/n", optarg );
Break;
}
}
Return 0;
}

Running result: $./opt_parse_demo-n
My name is lyong.
$./Opt_parse_demo-G
Her name is xxiong.
$./Opt_parse_demo-l forever
Our love is forever
$./Opt_parse_demo-NGL forever
My name is lyong.
Her name is xxiong.
Our love is forever

6. Change the output behavior of getopt () on the parameter information of the wrong command line.

Incorrect calling is inevitable. This error can be caused by Invalid command line options or missing option parameters. Under normal circumstances, getopt () will output its own error information for these two cases and return '? '. To verify this, you can modify the code in Listing 2 above.
Listing 3: # include <stdio. h>
# Include <unistd. h>

Int main (INT argc, char ** argv)
{
Int OC;/* option character */
Char * B _opt_arg;/* option parameter string */

While (OC = getopt (argc, argv, "NGL :"))! =-1)
{
Switch (OC)
{
Case 'N ':
Printf ("My name is lyong./N ");
Break;
Case 'G ':
Printf ("Her name is xxiong./N ");
Break;
Case 'l ':
B _opt_arg = optarg;
Printf ("Our love is % s/n", optarg );
Break;
Case '? ':
Printf ("arguments error! /N ");
Break;
}
}
Return 0;
}

Enter an incorrect command line and the result is as follows: $./opt_parse_demo-l
./Opt_parse_demo: option requires an argument -- l
Arguments error!

Most of the time, we do not want to output any error messages, or even output custom error messages. You can use the following two methods to change the error message output behavior of the getopt () function:
Before calling getopt (), set opterr to 0. In this way, you can force the getopt () function to output no messages when it finds an error.
If the first character of the optstring parameter is a colon, The getopt () function will remain silent and return different characters according to the error, as shown below:
"Invalid option" -- getopt () returns '? And optopt contains invalid option characters (this is a normal behavior ).
"Missing option parameter" -- getopt () returns ':'. If the first character of optstring is not a colon, getopt () returns '? ', Which makes this situation different from the case where the invalid option is used.
It is useless to say more. Test it.
Listing 4: # include <stdio. h>
# Include <unistd. h>

Int main (INT argc, char ** argv)
{
Int OC;/* option character */
Char EC;/* invalid option character */
Char * B _opt_arg;/* option parameter string */

While (OC = getopt (argc, argv, ": NGL :"))! =-1)
{
Switch (OC)
{
Case 'N ':
Printf ("My name is lyong./N ");
Break;
Case 'G ':
Printf ("Her name is xxiong./N ");
Break;
Case 'l ':
B _opt_arg = optarg;
Printf ("Our love is % s/n", optarg );
Break;
Case '? ':
EC = (char) optopt;
Printf ("invalid option character/'% C /'! /N ", EC );
Break;
Case ':':
Printf ("the option parameter is missing! /N ");
Break;
}
}
Return 0;
}

Test result: $./opt_parse_demo-
Invalid option character 'a '!
$./Opt_parse_demo-l
The option parameter is missing!

7. Features of The getopt () function provided by GNU

The getopt () function designed above is provided by the Unix support team. When it is executed, it stops searching for options as soon as it encounters a command line parameter that does not start. The getopt () function provided by GNU is different from the getopt () function. It scans the entire command line to find options. When the GNU getopt () function is called and the command line parameters are processed, it re-arranges the elements in argv so that when the re-arrangement ends, all options are moved to the front and the code that continues to check the remaining parameters in argv [optind] To argv [argc-1] still works, but in any case, when the special parameter '--' is met, the scan of the option is ended.

You can enter an out-of-order command line to view opt_parse_demo output: $./opt_parse_demo-l forever a B c d-g-n
Our love is forever
Her name is xxiong.
My name is lyong.

The second feature of GNU getopt () is that you can use a special first character in optstring to change the default behavior of getopt:
Optstring [0] = '+', which is similar to getopt () provided by the Unix Support Team.
Optstring [0] = '-'. Each parameter in the command line is obtained in optarg.
In the preceding two cases, ':' can be used as the second character.
The third feature of GNU getopt () is that the option character in optstring is followed by two colons, which allows this option to have optional option parameters. If the option parameter does not exist, GNU getopt () returns the option character and sets optarg to null.
8. GNU long option command line Parsing

In 1990s, Unix applications began to support long options, that is, a pair of short dashes, a descriptive option name, and a parameter that uses equal signs to connect to options.

GNU provides the getopt-long () and getopt-long-only () functions to support command line parsing of long options. The latter's long option string starts with a short horizontal line, instead of a pair of dashes.

Getopt_long () is a getopt () version that supports both long and short options. The following is their declaration: # include <getopt. h>

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 );

The first three parameters of getopt_long () are the same as those of getopt (). The first three parameters are an array pointing to the option structure. The option structure is called a "long option table ". If the longindex parameter is not set to null, it points to a variable, which is assigned the index value of the long option in longopts, which can be used for error diagnosis.

The statement of the Option structure in getopt. H is as follows: struct option {
Const char * Name;
Int has_arg;
Int * flag;
Int val;
};

The elements in the structure are described as follows:
Const char * Name
This is the option name, with no Dash in front. For example, "help" and "verbose.
Int has_arg
Specifies whether option parameters are available. If yes, which type of parameter is used, its value must be one of the following tables. Symbol constant numerical meaning
No_argument 0 option no Parameter
Parameters required for the required_argument 1 option
Optional_argument 2 Option parameter optional

Int * flag
If the pointer is null, getopt_long () returns the value in the Val field of the structure. If the pointer is not null, getopt_long () will fill in the value in the Val field in the variable it refers to, and getopt_long () will return 0. If the flag is not null but no long option is found, the value of the variable to which it points remains unchanged.
Int Val
This value is the returned value when the long option is found, or the value in * flag is loaded when the flag is not null. In typical cases, if the flag is not null, Val is a real/false value, such as 1 or 0. If the flag is null, Val is usually a character constant, if the length option is the same as the short option, the character constant should be the same as the parameter of this option in optstring.

Each long option has a separate entry in the long option table, which must be filled with the correct value. The value of the last element in the array should be all 0. Arrays do not need to be sorted. getopt_long () performs linear search. However, sorting by long names makes it easier for programmers to read.

The usage of the flag and Val mentioned above seems a bit confusing, but they are very useful, so it is necessary to thoroughly understand them.

Most of the time, programmers will set some tag variables during option Processing Based on the options found by getopt_long (). For example, when getopt () is used, the following program format is often made: int do_name, do_gf_name, do_love;/* mark the variable */
Char * B _opt_arg;

While (C = getopt (argc, argv, ": NGL :"))! =-1)
{
Switch (c ){
Case 'N ':
Do_name = 1;
Case 'G ':
Do_gf_name = 1;
Break;
Break;
Case 'l ':
B _opt_arg = optarg;
......
}
}

When the flag is not null, getopt_long * () will set the flag variable for you. That is to say, in the above Code, the processing of the options 'N' and 'L' is only set some tags. If the flag is not null, getopt_long () you can automatically set a tag for the tag variables corresponding to each option so that the two conditions in the preceding switch statement can be reduced to one. The following is an example of a long option table and corresponding processing code.
Listing 5:
# Include <stdio. h>
# Include <getopt. h>

Int do_name, do_gf_name;
Char * l_opt_arg;

Struct option longopts [] = {
{"Name", no_argument, & do_name, 1 },
{"Gf_name", no_argument, & do_gf_name, 1 },
{"Love", required_argument, null, 'L '},
{0, 0, 0, 0 },
};

Int main (INT argc, char * argv [])
{
Int C;
While (C = getopt_long (argc, argv, ": L:", longopts, null ))! =-1 ){
Switch (c ){
Case 'l ':
Rochelle opt_arg = optarg;
Printf ("Our love is % s! /N ", l_opt_arg );
Break;
Case 0:
Printf ("getopt_long () Setting variable: do_name = % d/N", do_name );
Printf ("getopt_long () Setting variable: do_gf_name = % d/N", do_gf_name );
Break;
}
}
Return 0;
}

Before testing, let's review the pointer flag in the option structure. If the pointer is null, getopt_long () returns the value in the Val segment of the structure. If the pointer is not null, getopt_long () will fill in the value in the Val field in the variable to which it points, and getopt_long () will return 0. If the flag is not null but no long option is found, the value of the variable to which it points does not change.

The following is a test: $./long_opt_demo -- name
Getopt_long () variable: do_name = 1
Getopt_long () variable: do_gf_name = 0

$./Long_opt_demo -- gf_name
Getopt_long () variable: do_name = 0
Getopt_long () variable: do_gf_name = 1

$./Long_opt_demo -- love forever
Our love is forever!

$./Long_opt_demo-l forever
Our love is forever!

After the test, you should be touched. So far, we have discussed flag and Val. The following summarizes the meanings of various returned values of get_long (): The returned values include meanings.
0 getopt_long () sets a flag. Its value is the same as the value of the Val field in the option structure.
1 optarg records a command line parameter.
'? 'Invalid Option
':' Option parameter missing
'X' option character 'X'
-1 option resolution ended

From a practical point of view, we expect each long option to correspond to a short option. In this case, in the option structure, as long as the flag is set to null, set Val to the short option character corresponding to the long option. For example, the program in listing 5 is modified as follows.
Listing 6: # include <stdio. h>
# Include <getopt. h>

Int do_name, do_gf_name;
Char * l_opt_arg;

Struct option longopts [] = {
{"Name", no_argument, null, 'n '},
{"Gf_name", no_argument, null, 'G '},
{"Love", required_argument, null, 'L '},
{0, 0, 0, 0 },
};

Int main (INT argc, char * argv [])
{
Int C;
While (C = getopt_long (argc, argv, ": L:", longopts, null ))! =-1 ){
Switch (c ){
Case 'N ':
Printf ("My name is lyr./N ");
Break;
Case 'G ':
Printf ("Her name is BX./N ");
Break;
Case 'l ':
Rochelle opt_arg = optarg;
Printf ("Our love is % s! /N ", l_opt_arg );
Break;
}
}
Return 0;
}

The test result is as follows: $./long_opt_demo -- name -- gf_name -- love forever
My name is lyr.
Her name is BX.
Our love is forever!

$./Long_opt_demo-ng-l forever
My name is lyr.
Her name is BX.
Our love is forever!

9. Use GNU getopt () or getopt_long () on a platform other than Linux ()
Just copy the source file (http://sourceware.org/glibc/) from the CVS file of the GNU program or gnu c library (glibc ). The source files are getopt. H, getopt. C, and getoptl. C. include these files in your project. In addition, the best copying. Lib file in your project is included, because the content of GNU lgpl (GNU Library Public License) is included in all the files named copying. Lib. When nothing happens, read the Free Software License Agreement and feel the spirit of Lei Feng.

Note that # include "getopt. H ", instead of # include <getopt. h>, the former will first find getopt in the current directory. h.

If you are a Windows platform user, you can try it out. I hope you can give your feedback here. Thank you.
10. Conclusion
The process sequence must be able to quickly process various options and parameters without wasting too much time on developers. At this point, both gui (graphical user interaction) Programs and Cui (command line interaction) programs are the primary tasks. The difference lies only in the different implementation methods. Gui interacts with each other through graphical controls such as menus and dialogs, while Cui uses plain text interaction. Each has its own advantages and disadvantages. In program development, Cui is the preferred solution for many testing programs.

The getopt () function is a standard library call that allows you to use direct while/switch statements to conveniently process command line parameters and check options (with or without additional parameters) one by one ). Similar to getopt_long (), getopt_long () allows more descriptive long options to be processed without additional work, which is very popular among developers.

Now that you know how to easily process command line options, you can focus on improving the command line of your program and add support for long options, or any other options that are shelved because you do not want to add additional command line options to the program for processing. But do not forget to record all your options and parameters somewhere, and provide some built-in help functions to help forgetful users.
References
Use getopt () to execute command line processing Chris herborth (chrish@pobox.com ).
Linux programming by example Arnold Robbins.

Re: http://www.cublog.cn/u/18537/showart.php? Id = 125055
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.