10.3. Interpreting program argumentsThe loop used to examine the program arguments in the example above is
a common C idiom which you will see in many other programs. An additional
common idiom is to use ‘options’ to control the behaviour of the
program (these are also sometimes called switches or flags). Arguments which
start with a ‘ progname -abxu file1 file2 progname -a -b -x -u file1 file2 The idea is that each of the options selects a particular aspect from the
program's repertoire of features. An extension to that idea is to allow
options to take arguments; if the progname -x arg file1 so that the progname -xarg file1 In either of the above cases, the options routine returns the character
‘ To use this routine, a program must supply a list of valid option letters
in the form of a string; when a letter in this string is followed by
a ‘ It seems to be a fact of life that functions which scan text strings looking for various combinations or patterns within them end up being hard to read; if it's any consolation they aren't all that easy to write either. The code that implements the options is definitely one of the breed, although by no means one of the worst:
/*
* options() parses option letters and option arguments from the argv list.
* Succesive calls return succesive option letters which match one of
* those in the legal list. Option letters may require option arguments
* as indicated by a ':' following the letter in the legal list.
* for example, a legal list of "ab:c" implies that a, b and c are
* all valid options and that b takes an option argument. The option
* argument is passed back to the calling function in the value
* of the global OptArg pointer. The OptIndex gives the next string
* in the argv[] array that has not already been processed by options().
*
* options() returns -1 if there are no more option letters or if
* double SwitchChar is found. Double SwitchChar forces options()
* to finish processing options.
*
* options() returns '?' if an option not in the legal set is
* encountered or an option needing an argument is found without an
* argument following it.
*
*/
#include <stdio.h>
#include <string.h>
static const char SwitchChar = '-';
static const char Unknown = '?';
int OptIndex = 1; /* first option should be argv[1] */
char *OptArg = NULL; /* global option argument pointer */
int options(int argc, char *argv[], const char *legal)
{
static char *posn = ""; /* position in argv[OptIndex] */
char *legal_index = NULL;
int letter = 0;
if(!*posn){
/* no more args, no SwitchChar or no option letter ? */
if((OptIndex >= argc) ||
(*(posn = argv[OptIndex]) != SwitchChar) ||
!*++posn)
return -1;
/* find double SwitchChar ? */
if(*posn == SwitchChar){
OptIndex++;
return -1;
}
}
letter = *posn++;
if(!(legal_index = strchr(legal, letter))){
if(!*posn)
OptIndex++;
return Unknown;
}
if(*++legal_index != ':'){
/* no option argument */
OptArg = NULL;
if(!*posn)
OptIndex++;
} else {
if(*posn)
/* no space between opt and opt arg */
OptArg = posn;
else
if(argc <= ++OptIndex){
posn = "";
return Unknown;
} else
OptArg = argv[OptIndex];
posn = "";
OptIndex++;
}
return letter;
}Example 10.2 |
The C BookThis book is published as a matter of historical interest. Please read the copyright and disclaimer information. GBdirect Ltd provides up-to-date training and consultancy in C, Embedded C, C++ and a wide range of other subjects based on open standards if you happen to be interested. |
|
West Yorkshire Office
GBdirect Ltd
Training: 0800 651 0338 Please call between 0900 and 1700 (UK time) on Monday to Friday South East Regional Office
GBdirect Ltd
Training: 0800 651 0338 Please call between 0900 and 1700 (UK time) on Monday to Friday Please note: |