Introduction
CCommandLineParameters
is a C/C++ class to help you process
command line arguments.
Yes, this is yet another "Command Line" processor. But in my opinion,
the others I've seen don't have the flexibility or common usage standards often
used command line tools switch options.
CCommandLineParameters
is designed to provide the following
common/standard requirements:
- Implicit or explicit help option.
- Usage of both slash ("/") or dash ("-") switch characters
- Support to add more switch characters
- Switch case sensitivity support
- Switch abbreviation support
- Switch default value support
- First Non Switch Parameter support
- Support for Quoted parameters
Nomenclature
The following legend is used to describe the
CCommandLineParameters
class:
Command Line |
The string passed to a program including the name of
the current program.
|
Parameter Line |
The string passed to a program excluding the name of
the current program.
|
Arguments |
The words in the parameter line each separated by
space. Argument 1 is the first word, argument 2 is the same word, etc.
Argument 0 is the name of the program. Please note that a double quote (")
is used to combine multiple words are one argument.
example: President
"George Bush"
The above is 2 arguments separate arguments, president and George
Bush.
|
Parameters |
Same as arguments
|
Switch |
An argument or parameter which begins with a switch
character. By default, the switch characters are dash ("-" or forward slash
("/")
|
Abbreviated Switch |
A switch that offers an abbreviation
shortcut.
Example: /s*end
Allows for /send or /s to be
used.
|
Non-Switch |
An argument or parameter which DOES NOT begin with a
switch character.
|
switch value |
The value assigned to a switch. |
argument or parameter index |
The index of the argument on the command line.
|
The following is standard command line syntax information which will be
helpful to you when you wish to document or describe the possible command line
parameters for your application in a help display:
[] |
When a parameter is surrounded with square brackets,
this typically means the parameter is optional. The parameter is not
required for normal operations of your program.
example: program.exe
[-p1]
|
<> |
When a parameter is surrounded with angle brackets,
this typically means the parameter is required for normal operations of your
program.
example: program.exe <filename>
|
| |
The vertical bar means a choice between one parameter
or parameter value is acceptable.
example: program.exe
</device:com1|com2>
|
For example, suppose an application describes the following command line
syntax:
program.exe <p1> [-p2 <v2>] [[/p3 [v3]]
[/p4]] [/p5 <v5|w5>]
By following the standard syntax, you can easily understand what the required
and optional parameters for any application.
In this example, p1 is a required parameter. The program will not run
if it is not passed. The switches /p2, /p3, /p4 and /p5 are
optional. If p2 is used, then v2 is required. If p3 is used, then V3
and /p4 are optional. However, the parameters v3 and /p4 are only
valid if /p3 is used in the first place. If /P5 is used, the valid values
are v5 or w5.
This basic syntax is standard across many platforms.
Using the code
Using CCommandLineParameters
is very simple. Simply instantiate
or add an object like so to your source code:
CCommandLineParameters clp;
The constructor offer an option to pass the switch characters which are by
default, "-/". If you wish to change the switch characters, you can do so
by passing a string defining the characters to the constructor:
CCommandLineParameters clp("-/\\"); /* dash, forward and back slash*/
The basic and most common usage at this point is the Switch() function. It
will cover 80% of your needs. All other member functions are based on the
Switch() function to give you other capabilities.
Here is a fast "get started" example:
Suppose our program "sendfile.exe" has a command line syntax:
sendfile.exe <filename> <-h*sot
<hostname>> [-p*ort <port#>]
then the following code will satisfy the syntax:
void usage()
{
print("SendFile v1.0 Copyright (c) 2003 MyCompany.com\n");
print("usage: <filename> <-h*sot <hostname>> [-p*ort <port#>]\n");
}
void main()
{
CCommandLineParameters clp;
if (clp.Help(TRUE)) {
usage();
return;
}
CString filename = clp.FirstNonSwitchStr();
CString hostname = clp.GetSwitchStr("h*ost");
DWORD deport = clp.GetSwitchInt("p*ort",80);
if (clp.FirstNonSwitchIndex() != 1) {
print("! syntax error: filename required\n");
usage();
return;
}
if (hostname.IsEmpty()) {
print("! syntax error: no host defined\n");
usage();
return;
}
Reference Guide
The following are the members of the CCommandLineParameters
class.
BOOL CheckHelp(const BOLO bNoSwitches =
FALSE);
Return TRUE if parameter #1 is "?", "/?" or "-?". If you want
to return TRUE when no parameters are passed, then call CheckHelp(TRUE);
Example:
CCommandLineParameters clp;
if (clp.CheckHelp(TRUE)) {
ShowHelp();
exit(1);
}
CString CommandLine();
Return the entire command line as a string, including the current
program name.
CString ParamLine();
Return the entire command line as a string, excluding the current
program name.
int ParamCount();
Return the total number of parameters or arguments on the command line,
including switches. This will always be a minimum of 1, which includes the
parameter #0 the name of the current application.
int SwitchCount();
Return the total number of switch options on the command line.
CString ParamStr(int index, const BOOL bGetAll =
FALSE);
Return the string at parameter #index. If bGetall is TRUE, then return
the string starting at parameter #index.
Example:
program.exe -email user@domain.com
-subject NewsLetter #22 March 2 1999
CCommandLineParameters clp;
CString email = clp.GetSwitchStr("-email");
CString Subject = "";
int i = clp.Switch("subject");
if (i > 0) Subject = clp.ParamStr(i+1,TRUE);
int ParamInt(int index);
Return the integer at parameter #index.
int FirstNonSwitchIndex();
Return the first parameter index where there the first non-switch parameter
occurs.
CString FirstNonSwitchStr();
Return the string where there the first non-switch parameter occurs.
See also GetNonSwitchStr().
int Switch(const char *sz, const BOOL bCase =
FALSE);
Switch() will return the parameter index if the switch exist. Return 0 if not
found.
The logic will allow for two types of switches:
/switch value
/switch:value
DO NOT PASS THE COLON. IT IS AUTOMATICALLY
CHECKED. In other words, the following statements are the
same:
Switch("server");
Switch("-server");
Switch("/server");
to handle the possible switch arguments and
retrieval of switch values:
/server:value
/server value
-server:value
-server value
If you wish to have an abbreviation, insert a star "*" character in the
switch at the position to indicate the number of abbreviated characters.
If you wish to make it case sensitive, then pass bCase as TRUE.
Example:
BOOL bStart = clp.Switch("st*art");
CString GetSwitchStr(const char *sz,
const char *szDefault = "",
const BOOL bCase = FALSE);
int GetSwitchInt(const char *sz,
const int iDefault = -1,
const BOOL bCase = FALSE);
Return the string or integer for a given switch. Optionally pass the
default value and if case sensitivity is to be used.
These functions support two types of switch inputs:
/switch:data
/switch data
Either format is acceptable.
CString GetNonSwitchStr(const BOOL bBreakAtSwitch = TRUE,
const BOOL bFirstOnly = FALSE);
Return the non switch string(s) depending on the values of bBreakAtSwitch and
bFirstOnly.
bBreakAtSwitch |
bFirstOnly |
Result |
TRUE |
FALSE |
Default Behavior, returns all strings
non-switch strings starting at the first one found, stopping at the first switch
found. |
TRUE |
TRUE |
returns the first non-switch string
starting at the first one found. |
FALSE |
TRUE |
returns the first non-switch
string. |
FALSE |
FALSE |
returns all the non-switch
strings. |
Examples:
program.exe file.txt -p:80 -H www.winserver.com
program.exe
file.txt -p:80 -h 208.247.131.9
int port = clp.GetSwitchInt("port",25,1);
CString host = clp.GetSwitchStr("HOST,"",1,TRUE);
CString ip = clp.GetSwitchStr("host,"",1,TRUE);
CString file = clp.GetNonSwitchString(TRUE,TRUE);
In the above example, the switch for H is case sensitive. In one case
(upper), it sets the host variable and in the lower case option it sets the ip
variable.
program.exe file1.txt file2.txt file2.txt -output out.txt
CString infiles = clp.GetNonSwitchString(TRUE,FALSE);
CString outfile = clp.GetSwitchStr("-output",1)
Points of Interest
This class works under console and GUI applications. A maximum of 100
parameters are possible. A possible enhancement is a syntax validation
parser. This would help reduce coding of valid parameter syntax.
History
v1.0p March 5, 2003 - Initial Public Release
About the Author
Hector Santos is the CTO of Santronics Software, Inc, developer of
WINSERVER (Wildcat! Interactive Net
Server), an integrated Dialup and Intranet Hosting Client/Server
System. Hector made his mark in the early Off-line Mail Reader/Door
days in the Fidonet Mail/File Network with the 1984 debut of the Silver Xpress
OffLine Mail Door/Reader System. Before the internet, we connected with
low speed modems and to read or create mail ONLINE was expensive. Silver Xpress
and other similar products made it feasible for millions of people world wide to
enjoy "BBSing" by downloading mail for offline reading and replying.
In 1992 with the internet coming and online communications becoming
more feasible, products like SX were beginning to die. Hector's next
product was Platinum Xpress, a P2P like system (we just didn't call it P2P) for
the automatic exchange of Mail and Files in a world wide network of Zones, Nets,
Nodes and Points users. This was called FidoNet and believe it not, there is
nothing in the market today to compares to the P2P technology found in
FidoNet. In 1996, with the success of PX, Hector purchased the
rights to a brand new product line called WINSERVER, a product way ahead of its
time. WINSERVER is now Santronics's flag ship product line, and it is a
leading provider for private intranet solutions, especially in the the Medical,
Health and Claims/Collection Industry where mail and files needs to be exchanges
in a Intranet manner using all kinds of connection devices, including direct
connect modems which still to this day, is probably still the most secured way
of transferring data without internet sniffing worries.