The getopt function can be used to conveniently process command line parameters. The function is prototype:
Int getopt (INT argc, char * const argv [], const char * optstring );
The following are key points:
1. argc, argv is the two of the main function. Optstring is the format string we provide, especially in the format string: indicates that the command option is followed by a value, for example :. /xtop-N 20-I 2 1111, Here optstring can be written as "N: I:", which indicates that N and I are command option, value must be given after the two options. If no value is given, value is not required after the option. There are also some conventions about optstring. For example, it has special meanings starting with +. For details, see man 3 getopt.
2. Return Value. Under normal circumstances, a char is returned, indicating the option letter currently analyzed. In this way, a switch can be used for processing. -1 is returned after all analyses are completed. If an option does not appear in optstring, getopt returns? (By default ). In fact, this is not so troublesome. Generally, after we list all the option letters that need to be processed in the coding process, we can use a default to regard the return values of any other getopt statements as illegal. Print: usage: A String like XXXX. Exit the program.
3. Note: The options we specified in optstring are not mandatory. For example, in the above example, we require that both options-N and-I must be set, and the user only gives one-N when executing the program, getopt cannot handle this issue. He just analyzed the token from the beginning to the end and gave us the option letter. Therefore, in this case, we need to check in the program whether users have set the mandatory options. Otherwise, an error is returned. In fact, according to the principle of option and argument, option should be optional. Otherwise, how is it called optiton? The full part set by the user should be forced to become argument, which is the most logical.
4. As mentioned above, for an option like-N 20, getopt returns the letter N. How can we get this 20? Getopt places the option value in a global variable named optarg and the type is char *. We can obtain this value by accessing optarg. If the option you write is-N2, getopt returns N and optarg value is-N2, which must be manually determined. Unless the user writes-N and the end is gone, according to The optstring requirements, getopt will print the error message and return ?.
5. Finally, about argument. That is, after getopt has analyzed all options, the final part is argument. In the above example,./xtop-N 20-I 2 1111, And the last 1111 is argument. Getopt sets the global variable optind (whose type is int). This optind is the first argument (that is, the token that does not start with-and is not the token of option value) the index in the argv array, that is, argv [optind] can retrieve this argument. It is very convenient. In this way, with this optind, you can write the option in a mixed way, or mix the argument and option into the command line, if you do not use it, you must put argument at the end of the command line.
Note that the code in xtop is attached. Getopt has some special descriptions and feature, which can be found in Man 3 getopt. In addition, there are functions such as getopt_long, which can be used to handle -- the long option of headers. This is also described in the man manual.
Int main (INT argc, char * argv [])
{
Int OPT;
// Argument Handling
While (OPT = getopt (argc, argv, "N: I: O :"))! =-1 ){
Switch (OPT ){
Case 'N ':
If (! String_is_int (optarg )){
Fprintf (stderr, "error: <times> shocould be an integer. Yours is % s \ n", optarg );
Goto failed;
}
Check_times = atoi (optarg );
Break;
Case 'I ':
If (! String_is_int (optarg )){
Fprintf (stderr, "error: <time interval> shocould be an integer. Yours is % s \ n", optarg );
Goto failed;
}
Check_interval = atoi (optarg );
Break;
Case 'O ':
Output_file = (char *) malloc (strlen (optarg) + 1 );
If (output_file = NULL ){
Fprintf (stderr, "error: malloc for output file failed. \ n ");
Goto failed;
}
Strcpy (output_file, optarg );
Break;
Default:
Printf ("Usage: xtop-n <times>-I <time interval> [-O <output file>] <pid> \ n ");
Goto failed;
}
}
// Check whether the-N &-I are set
If (check_times <= 0 | check_interval <= 0 ){
Fprintf (stderr, "Usage: xtop-n <times>-I <time interval> [-O <output file>] <pid> \ n ");
Fprintf (stderr, "also make sure your <times>, <time interval> are positive integers. \ n ");
Goto failed;
}
If (optind> = argc ){
Fprintf (stderr, "error: <pid> argument can't be found. \ n ");
Goto failed;
}
If (! String_is_int (argv [optind]) {
Fprintf (stderr, "error: <pid> shocould be an integer. Yours is % s \ n", argv [optind]);
Goto failed;
}
PID = atoi (argv [optind]);
If (PID <= 0 ){
Fprintf (stderr, "error: Illegal <pid> argument. PID shocould be a positive integer. Yours is % d \ n", pid );
Goto failed;
}
//-O <output file> is optional, so check whether the user set this
// Xtop. out is the default Output Filename
If (output_file = NULL ){
Printf ("begin analyzing process % d, checking % d times after every % d seconds. Record results into xtop. Out \ n ",
PID, check_times, check_interval );
} Else {
Printf ("begin analyzing process % d, checking % d times after every % d seconds. Record results into % s \ n ",
PID, check_times, check_interval, output_file );
}
............
}