31
\$\begingroup\$

In our console app, the parsing of application arguments is done like so:

using System.Linq;

namespace Generator
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            var param1 = args.SingleOrDefault(arg => arg.StartsWith("p1:"));
            if (!string.IsNullOrEmpty(param1))
            {
                param1  = param1.Replace("p1:", "");
            }
            //...
        }
    }
}

It's supposed to be called like this:

`Generator.exe p1:somevalue`

Is there a better/simpler way to parse arguments?

\$\endgroup\$
1
  • \$\begingroup\$ Also, the FubuCore library has a pretty powerful and self-documenting command line args parser, that I briefly described here \$\endgroup\$ Mar 24, 2012 at 11:22

6 Answers 6

27
\$\begingroup\$

I'd recommend taking advantage of the excellent Mono.Options module. It's a single .cs file you can drop in to your solution and get full-featured parsing of GNU getopt-style command lines. (Things like -x -y -z, which is equivalent to -xyz, or -k value, or --long-opt, and so forth.)

\$\endgroup\$
5
  • \$\begingroup\$ from 2018: Microsoft added their own code to the file. Now you CAN NOT use it as a separated file. Thanks MS. This is the latest tag without MS's intervention I've found \$\endgroup\$ Apr 13, 2018 at 16:40
  • 2
    \$\begingroup\$ @maxkoryukov I don't get your logic. It's still licensed under the MIT license, which explicitly says it can be copied in part or in whole, as long as the license is included with it. So as of this writing in 2019 you can still take this file on its own. Unless you have something about irrationally avoiding everything Microsoft has ever touched, in which case you should know that StackExchange runs on Microsoft software. \$\endgroup\$
    – Nic
    Jan 12, 2019 at 20:32
  • \$\begingroup\$ @NicHartley, you are right, it is still MIT-licensed. Sorry, but I don't remember what I meant then, so I can't explain my comment now... Yes, I don't like the MS-development way and their style in the software world, overall. But who am I ))) \$\endgroup\$ Jan 14, 2019 at 16:54
  • \$\begingroup\$ @maxkoryukov urgh, sorry for my tone there -- I genuinely didn't mean any sarcasm, but rereading my comment it really sounded like it. And yeah, it's perfectly fair to dislike Microsoft. My issue is just with people avoiding everything they've ever had contact with, even indirectly by someone becoming a developer for them, because of some "taint" that they have, and (as it's been MIT-licensed the whole time) that's what I immediately jumped to. I guess I like imagining the worst of people. Sorry :( \$\endgroup\$
    – Nic
    Jan 14, 2019 at 17:00
  • 1
    \$\begingroup\$ @NicHartley don't apologize;) there was an error in my comment (and it is still there) — I can't explain that comment in any other way. And I don't know why I wrote that comment. Mono.Options is still a decent piece of C# code, in spite of the fact of MS interventions \$\endgroup\$ Jan 14, 2019 at 17:44
23
\$\begingroup\$

With such an implementation you will have to repeat yourself for each param.

Alternative:

var parsedArgs = args
    .Select(s => s.Split(new[] {':'}, 1))
    .ToDictionary(s => s[0], s => s[1]);
string p1 = parsedArgs["p1"];
\$\endgroup\$
4
  • 1
    \$\begingroup\$ +1: I would have used '='. And check that arguments are prefixed with '--'. And what about where the value is the next argument not in the same argument? \$\endgroup\$ Jan 28, 2011 at 18:19
  • \$\begingroup\$ @Martin why would you prefix arguments with '--'? \$\endgroup\$
    – frennky
    Jan 28, 2011 at 18:38
  • 1
    \$\begingroup\$ @frennky: Its sort of a standard for command line arguments (--<longName> or -<shortName>). It separates flags (which modify behavior) from inputs/outputs. But re-reading your original question I was over generalizing and this is not what you want. \$\endgroup\$ Jan 28, 2011 at 20:15
  • \$\begingroup\$ @frennky - I agree with Martin, if you are writing an application which somebody (except you) will use then you should read about console argument standarts. As far as I know '--' is kind of *nix style, in windows it is more about slashes. \$\endgroup\$
    – Snowbear
    Jan 28, 2011 at 20:22
4
\$\begingroup\$

There's a related question on Stack Overflow. There, the consensus seems to be Mono.Options as already suggested here by josh3736.

\$\endgroup\$
2
  • \$\begingroup\$ Read further down the list of answers on that SO question and you'll see that ndesk.org/Options has 2x the upvotes of the accepted answer. \$\endgroup\$ Mar 4, 2011 at 17:00
  • 1
    \$\begingroup\$ Actually, the answer you refer to says "I would strongly suggest using NDesk.Options (Documentation) and/or Mono.Options (same API, different namespace)." \$\endgroup\$
    – Don Kirkby
    Mar 4, 2011 at 18:00
2
\$\begingroup\$

I usually don't use complex command line arguments, so I use a very Simple Command Line Arguments Parser, but it can be used as a foundation for your own application specific parameter presenter.

\$\endgroup\$
1
\$\begingroup\$

You could use foreach for iterating through the agruments and then for your argument with index 1 you could use regular expression to retrieve parsed text after p1:

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I was hoping to avoid using loops. As for Regex, I think it would be too much, the pattern is quite simple. \$\endgroup\$
    – frennky
    Jan 28, 2011 at 18:36
-2
\$\begingroup\$

Please check solution from link. IT uses linq. It short and reuseble in my opinion. Provides extension method so you just do somethink like:

args.Process(
           () => Console.WriteLine("Usage is switch1=value1,value2 switch2=value3"),
           new CommandLine.Switch("switch1",
               val => Console.WriteLine("switch 1 with value {0}",
                   string.Join(" ", val))),
           new CommandLine.Switch("switch2",
               val => Console.WriteLine("switch 2 with value {0}",
                   string.Join(" ", val)), "s1"));
   }

for details please visit my blog

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.