Click here to Skip to main content
15,881,424 members
Articles / Programming Languages / C#

Parsing Command Line Arguments

Rate me:
Please Sign up or sign in to vote.
4.71/5 (25 votes)
26 Apr 2009CPOL2 min read 61.8K   494   83  
The CommandLineParser library provides a simple way to define command line arguments and parse them in your application.
For applications that have one or two arguments, you could probably manage with some switches and ifs, but when there are more arguments, you could use a CommandLineParser library and thus make your code cleaner and more elegant.
#define skipexceptions
#define autoargs 
    //uncomment autoargs defined, to see a declarative way of using the library 

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using CommandLineParser;
using CommandLineParser.Arguments;
using CommandLineParser.Exceptions;

namespace ParserTest
{
    class Program
    {
        /// <summary>
        /// example class used to demonstrate attributes with 
        /// custom values
        /// </summary>
        class Point
        {
            public int x;
            public int y;

            public override string ToString()
            {
                return String.Format("Point[{0};{1}]", x, y);
            }

            public static Point Parse(string stringValue, System.Globalization.CultureInfo cultureInfo)
            {
                if (stringValue.StartsWith("[") && stringValue.EndsWith("]"))
                {
                    string[] parts =
                        stringValue.Substring(1, stringValue.Length - 2).Split(';', ',');
                    Point p = new Point();
                    p.x = int.Parse(parts[0], cultureInfo);
                    p.y = int.Parse(parts[1], cultureInfo);
                    return p;
                }
                else
                    throw new CommandLineArgumentException("Bad point format", "point");
            }
        }

#if autoargs
        class ParsingTarget
        {
            [SwitchArgument('s', "show", true, Description = "Set whether show or not")]
            public bool show;

            private bool hide;
            [SwitchArgument('h', "hide", false, Description = "Set whether hid or not")]
            public bool Hide
            {
                get { return hide; }
                set { hide = value; }
            }

            [ValueArgument(typeof(decimal), 'v', "version", Description = "Set desired version")]
            public decimal version;

            [ValueArgument(typeof(string), 'l', "level", Description = "Set the level")]
            public string level;

            [ValueArgument(typeof(Point), 'p', "point", Description = "specify the point")]
            public Point point;

            [BoundedValueArgument(typeof(int), 'o', "optimization", 
                MinValue = 0, MaxValue = 3, Description = "Level of optimization")]
            public int optimization;

            [EnumeratedValueArgument(typeof(string),'c', "color", AllowedValues = "red;green;blue")]
            public string color;

            [ValueArgument(typeof(int), 'i', "number", Description = "numbers - test of multivalue array binding", AllowMultiple = true)]
            public int[] someNumbers;

            [ValueArgument(typeof(string), 'n', "name", Description = "names - test of multivalue collection binding", AllowMultiple=true)]
            public List<string> someNames = new List<string>();
        }
#endif

        static void Main(string[] args)
        {
            CommandLineParser.CommandLineParser parser = new CommandLineParser.CommandLineParser();

#if autoargs
#else
            SwitchArgument showArgument = new SwitchArgument(
                's', "show", "Set whether show or not", true);

            SwitchArgument hideArgument = new SwitchArgument(
                'h', "hide", "Set whether hid or not", false);

            ValueArgument<string> level = new ValueArgument<string>(
                'l', "level", "Set the level");

            ValueArgument<decimal> version = new ValueArgument<decimal>(
                'v', "version", "Set desired version");

            ValueArgument<Point> point = new ValueArgument<Point>(
                'p', "point", "specify the point");

            BoundedValueArgument<int> optimization = new BoundedValueArgument<int>(
                'o', "optimization", 0, 3);

            EnumeratedValueArgument<string> color = new EnumeratedValueArgument<string>(
                'c', "color", new string[] {"red", "green", "blue"});

            point.ConvertValueHandler = delegate(string stringValue)
                                            {
                                                if (stringValue.StartsWith("[") && stringValue.EndsWith("]"))
                                                {
                                                    string[] parts =
                                                        stringValue.Substring(1, stringValue.Length - 2).Split(';', ',');
                                                    Point p = new Point();
                                                    p.x = int.Parse(parts[0]);
                                                    p.y = int.Parse(parts[1]);
                                                    return p;
                                                }
                                                else
                                                    throw new CommandLineArgumentException("Bad point format", "point");
                                            };

            

            parser.Arguments.Add(showArgument);
            parser.Arguments.Add(hideArgument);
            parser.Arguments.Add(level);
            parser.Arguments.Add(version);
            parser.Arguments.Add(point);
            parser.Arguments.Add(optimization);
            parser.Arguments.Add(color);

            parser.ShowUsage();
#endif

            Examples examples = new Examples();
#if autoargs
            ParsingTarget p = new ParsingTarget();
            // read the argument attributes 
            parser.ExtractArgumentAttributes(p);
#endif
            foreach (Example example in examples)
            {
                try
                {
                    Console.WriteLine("INPUT: {0}", example._commandline);


              
                    parser.ParseCommandLine(example.commandline);
                    parser.ShowParsedArguments();
                    Console.WriteLine("RESULT: OK");
                }
                catch(MandatoryArgumentNotSetException e)
                {
                    parser.ShowParsedArguments();
                    Console.WriteLine("RESULT: Parsing OK, but mandatory argument not set: {0}", e.Argument);
                }

#if skipexceptions
                catch (CommandLineException e)
                {
                    Console.WriteLine("RESULT: EXC - " + e.Message);
                    
                }
#endif
                finally
                {
                    Console.WriteLine("EXPECTED: {0}", example.expectation);
                }
                Console.WriteLine();
                Console.WriteLine();
            }

            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("FINISHED");
            Console.ReadLine();
        }
    }

    /// <summary>
    /// example command line
    /// </summary>
    struct Example
    {
        public string _commandline;
        public string[] commandline;
        public string expectation;

        public Example(string commandline, string expectation)
        {
            this._commandline = commandline;
            this.commandline = commandline.Split(' ');
            this.expectation = expectation;
        }
    }


    /// <summary>
    /// some example command lines
    /// </summary>
    class Examples: IEnumerable<Example>
    {
        IEnumerator IEnumerable.GetEnumerator()
        {
            return ((IEnumerable<Example>) this).GetEnumerator();
        }

        public IEnumerator<Example> GetEnumerator()
        {
 

            yield return new Example(
                "--name john --name martin --name peter",
                "OK"
                );

            yield return new Example(
                "-i 1 -i 2 -i 3",
                "OK"
                );
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Junior)
Czech Republic Czech Republic
I am a computer science student at Charles University in Prague. I work as a developer of CRM and informational systems.

Comments and Discussions