![]() |
General Programming »
Algorithms & Recipes »
Parsers and Interpreters
Intermediate
Yet Another Command Line Argument ParserBy Sean Michael MurphyA reusable library to obtain command line parameters passed to executables in an orderly manner. |
C#.NET 1.0, .NET 1.1, Win2K, WinXP, Win2003VS.NET2003, Dev
|
|
Advanced Search |
|
|
|
||||||||||||||||

When writing applications that require run-time information supplied by a command shell, the best way to communicate the additional information to your executable is via command line parameters. You frequently have to write code to parse the command line parameters looking for specific information to customize execution of your application. I'll show you how to write a reusable library callable from your code to expose the command line arguments as name-value pairs, allowing you to avoid having to write tedious parsing code over and over again in different projects.
In the "C" family of languages, including C, C++ and C#, command line information is conveyed by the command shell to the running executable using a string array passed to the static main() function. The string array is composed of the text that followed the executable name, chopped up into sub-strings delimited by the space character. See the image above.
If you force your users to specify all possible parameters on every execution in a specific order, you ease your parameter reading grief and can just jump to specific indexes of the args[] array to get the parameter values. If you have any consideration at all for your users and allow them to specify parameters in any order they choose, or allow your users to specify optional parameters, you have to write code to identify parameters by their name and then to read the value associated with that variable.
There are several hundred examples of code that does similar work written in C and C++, and a few written in C# (hence the project name prefix "Yet Another..."). This code is different from the others on CodeProject in that it allows you to specify additional information to the parsing process to allow for idiosyncrasies in your command line syntax, and also to allow for the run-time parameters supplied to your applications to be removed into separate files for organization and easy re-use.
The project consists of three classes enclosed in a single source code file:
ArgParser
VVPair
VVPairs ArgParser is the main class you instantiate, handing the constructor the args string array passed to your executable. Optionally, you can specify the character you want to use to mark your argument names and the character you want to use to separate your variable names from their values. It's really a matter of style, but you can configure the class to parse arguments that look like this:
c:\>YACLAPTester.exe /user:kim /test:yes /verbose
or like this:
c:\>YACLAPTester.exe -user=kim -test=yes -verbose
Just pass '/' and ':' to the ArgParser constructor used by your YACLAPTester application in the first case (or don't specify any characters -> these are the defaults) or '-' and '=' to the constructor in the latter case.
The VVPair class holds the name of a variable (user, test and verbose in the examples above) and its value (Kim, yes and a zero length string above). The VVPairs class is a collection class of these custom variable-value pair objects. I considered using one of the intrinsic name-value pair types like StringDictionary and DictionaryEntry but decided against it. The slight amount of extra code allows you to be more flexible in processing.
When instantiated, the ArgParser constructor starts a two-phase process.
The constructor iterates over the string array, and compares the initial character of each string in the array to two characters:
ArrayList object.
ArrayList with the other parameters. Lines in the file that begin with characters other than the variable definition character are ignored and assumed to be comments.
args array is neither the "@" sign nor the variable name character, it is ignored and not added to the ArrayList object. You can choose to be more assertive and throw an exception if the raw string does not start with the file specifier character, but I chose to just ignore them. You'll be in good company if you support command parameter files. Microsoft is using this technique in supplying parameters to the C# 2.0 command line compiler through response file specifiers. They use files that are named *.rsp, but I'm not fussy about the extension here.
Once phase I is complete, the ArrayList is full of the parameters found in the string array (and any expanded response files). The constructor will then loop through the ArrayList and examine each string. If the string starts with the variable specifier character, it will parse it into a new VVPair object, separating out the name of the variable from the value by the valueDelimiter character parameter, and add it to the VVPairs collection.
Once the VVPairs collection is populated at the end of the ArgParser constructor, you can allow the variables to be read by exposing an indexer property on the ArgParser class that returns a VVPair object based on a string passed to it. When I implemented the indexer property, I chose to return a new VVPair object if the name of the variable was not found in the collection, rather than null so you don't have to constantly test for uninitialized objects, and your code can look like this:
if (argParser["MyVariable"].Value == "true") {
// Do some processing here
}
rather than like this:
VVPair pair = argParser["MyVariable"];
if (pair != null) {
if (pair.Value == "true") {
// Do some processing here
}
}
Just compile the library, include it in your project (Console or Windows) and you can provide as much flexibility as your users need in initializing your application. The ArgParser class implements IDisposable, so just put it in a using{} block and it will clean up after itself nicely.
Nothing fancy about this code. Just drudge code that you've probably written a thousand times before.
| You must Sign In to use this message board. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 2 Jan 2005 Editor: Rinish Biju |
Copyright 2005 by Sean Michael Murphy Everything else Copyright © CodeProject, 1999-2009 Web16 | Advertise on the Code Project |