0

I want to parse CommandLine which can be in two formats:

  1. command 123 - command with 1 parameter (123)
  2. command 123,456 - command with 2 parameters (123 and 456)

Here command - command's name, followed by space ' ' and parameter(s): 123 or 123,456 which separated by comma ,

I've tried to achieve the goal with the code below:

        for (int i = 0; i <= CommandLine.TextLength; i++)
        {
            String[] CommandLineText = CommandLine.Text.Split(' ');
            String Commands = CommandLine.Text.ToLower().Trim();
            String Command = CommandLineText[0];
            String Values = CommandLineText[1];
            String[] Parameters = Values.Split(',');
            int X = Int32.Parse(Parameters[0]);
            int Y = Int32.Parse(Parameters[1]);
        }

The problem I'm having is that when the command is in the first format with only 1 number the second parameter becomes out of bounds.

Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215
IronMike
  • 15
  • 2
  • 3
    Hint: if I give you the input string `Hello there`, and tell you to split by commas, how many elements will be in the resulting array? – gunr2171 Nov 12 '21 at 13:07
  • 2
    Does this answer your question? [What is an IndexOutOfRangeException / ArgumentOutOfRangeException and how do I fix it?](https://stackoverflow.com/questions/20940979/what-is-an-indexoutofrangeexception-argumentoutofrangeexception-and-how-do-i-f) – gunr2171 Nov 12 '21 at 13:09
  • 1
    What are you doing with the outer for loop? `for (int i = 0; i <= CommandLine.TextLength; i++)` This seems pointless for your task... – Idle_Mind Nov 12 '21 at 13:19
  • So, what did *you* expect `Y` to become set to in the case of such commands? Why is there no logic here to make that happen? – Damien_The_Unbeliever Nov 12 '21 at 13:21
  • You need a conditional to not set `Y` if there isn't a second command (`if Parameters.Length < 2`)...Also I'm not sure what the `Commands` is for. – davidsbro Nov 12 '21 at 13:37

2 Answers2

0

Assuming you have some commands that take 1 argument, and others that take 2...

You need to take tiny steps so you can see at what point the parsing breaks down. This will also allow you to tell the user exactly where the error is located:

private void button1_Click(object sender, EventArgs e)
{
    String rawCommand = CommandLine.Text.ToLower().Trim();
    if (rawCommand.Length > 0)
    {
        String[] parts = rawCommand.Split(' ');
        if (parts.Length >= 2)
        {
            String command = parts[0];
            String[] args = parts[1].Split(',');
            if (args.Length == 1)
            {
                String arg1 = args[0];
                int X;
                if (Int32.TryParse(arg1, out X))
                {
                    // ... do something in here with "command" and "X" ...
                    Console.WriteLine("Command: " + command);
                    Console.WriteLine("X: " + X);
                }
                else
                {
                    MessageBox.Show("Invalid X Argument!");
                }
            }
            else if(args.Length >= 2)
            {
                String arg1 = args[0];
                String arg2 = args[1];
                int X, Y;
                if (Int32.TryParse(arg1, out X) && Int32.TryParse(arg2, out Y))
                {
                    // ... do something in here with "command" and "X" and "Y" ...
                    Console.WriteLine("Command: " + command);
                    Console.WriteLine("X: " + X);
                    Console.WriteLine("Y: " + Y);
                }
                else
                {
                    MessageBox.Show("Invalid X and/or Y Argument!");
                }
            }
        }
        else
        {
            MessageBox.Show("Command has no Parameters!");
        }
    }
    else
    {
        MessageBox.Show("Missing Command!");
    }           
}
Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
0

It seems you want something like this:

  using System.Linq;

  ....

  string CommandLine = "doIt 123,456";

  ....

  // Given Command Line we split it by space into two parts:
  // 0. command name
  // 1. command arguments
  string[] parts = CommandLine
    .ToLower()
    .Split(' ', 2, StringSplitOptions.RemoveEmptyEntries);

  // 1st part is a command name 
  command = parts[0];

  // 2nd part (if any) is parameters
  int[] Parameters = parts.Length <= 1
    ? new int[0]                        // We don't have parameters 
    : parts[1]
       .Split(',')                      // Split by comma
       .Select(item => int.Parse(item)) // Parse each argument as int
       .ToArray();                      // Organize them as an array

If you insist on having X and Y you have to be sure that Parameters is long enough:

  // let X = -1 if Parameters doesn't have it
  int X = Parameters.Length >= 1 ? Parameters[0] : -1;

  // let Y = -1 if Parameters doesn't have it
  int Y = Parameters.Length >= 2 ? Parameters[1] : -1;
Dmitry Bychenko
  • 180,369
  • 20
  • 160
  • 215