C# Command Line Arguments Parsing Class
This is code files for a class for easily parsing command line arguments into a dictionary.
Example 1:
:cmdargs.exe /firstarg=someValue -secondArg="The Center Cannot Hold" /beSilly
Argument: firstarg
Values:
someValue
Argument: secondarg
Values:
The Center Cannot Hold
Argument: besilly
Values:
true
Example 2:
:cmdargs.exe /multiVal=a /multiVal=b /multival=c
Argument: multival
Values:
a
b
c
Example 3:
:cmdargs.exe firstVal secondVal thirdVal
Argument: unnamed
Values:
firstVal
secondVal
thirdVal
Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MachineGods
{
/*
LICENSE
Copyright (c) 2009, Michael Lehman (http://www.machinegods.com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the Michael Lehman, machinegods.com, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
class CmdArgsMain
{
static void Main(string[] args)
{
Dictionary> dArgs = CmdArgs.Parse(args);
foreach (string key in dArgs.Keys)
{
Console.WriteLine("\n\nArgument: " + key);
Console.WriteLine("Values:");
foreach (string value in dArgs[key])
{
Console.WriteLine("\t" + value);
}
}
}
}
///
/// A class for parsing command line arguments.
///
/// Allows arguments to be passed in any of the following formats:
/// -name[=value]
/// /name[=value]
/// --name[=value]
/// value
///
/// The name used for an argument will be used as the key in the returned dictionary.
/// - the key will be converted to lower case
/// - the key must not contain spaces
/// - the key/name can be a letter, word, or phrase as desired as long as it doesn't have spaces
/// An equal sign must seperate the key and the value with no spaces around it
/// Quotes should be used to enclose a value with spaces, the value will be stored without any surrounding quotes
/// - (this is the behavior of the command prompt)
/// Duplicate values will not be stored
/// If non-named values are passed they will be stored in with a key of "unnamed"
/// If an argument is passed multiple times (or multiple unnamed values are passed), they will be stored in the array
/// Arguments passed in without a value will be stored with a value of "true"
///
internal class CmdArgs
{
///
/// Returns a dictionary of the arguments passed in
///
/// The command line arguments to be parsed
/// The parsed values in a dictionary
public static Dictionary> Parse(string[] args)
{
Dictionary> argsList = new Dictionary>();
foreach (string arg in args)
{
if (arg.StartsWith("-") || arg.StartsWith("/"))
{
//named value
//strip the leading characters
//split on the = sign
//convert the name to lower case
//trim and store
string tmpArg = arg;
if (tmpArg.StartsWith("--")) tmpArg = tmpArg.Substring(2); //be sure to test for double -- as a single will process this too
if (tmpArg.StartsWith("-") || tmpArg.StartsWith("/")) tmpArg = tmpArg.Substring(1);
if(tmpArg.Contains("=")) {
string name = tmpArg.Substring(0, tmpArg.IndexOf("=")).ToLowerInvariant();
string value = tmpArg.Substring(tmpArg.IndexOf("=") + 1).Trim();
if (argsList.Keys.Contains(name))
{
if(!argsList[name].Contains(value)) argsList[name].Add(value);
}
else
{
List tmpList = new List();
tmpList.Add(value);
argsList.Add(name, tmpList);
}
} else {
if (!argsList.Keys.Contains(tmpArg.ToLowerInvariant()))
{
List tmpList = new List();
tmpList.Add("true");
argsList.Add(tmpArg.ToLowerInvariant(), tmpList);
}
}
}
else
{
//unnamed value
//trim and store
if (argsList.Keys.Contains("unnamed"))
{
if (!argsList["unnamed"].Contains(arg.Trim())) argsList["unnamed"].Add(arg.Trim());
}
else
{
List tmpList = new List();
tmpList.Add(arg);
argsList.Add("unnamed", tmpList);
}
}
}
return argsList;
}
}
}
