1

(I have tried finding a similar problem with no luck, so I am hoping maybe someone can provide a solution)

I have a do while loop in my first class with the goal of looping until the user inputs Feet, Meters or Yards as follows:

string convert = "";

do
{
    Console.Clear();
    Console.WriteLine("What conversion: Feet, Meters, Yards");

    try
    {
        convert = Convert.ToString(Console.ReadLine());
    }
    catch (Exception)
    {
        Console.Clear();
        Console.WriteLine("Incorrect conversion");
        Console.ReadKey();
    }

    convert = Values.Input(convert);

    Console.WriteLine(convert);
    Console.ReadKey();
} while (_____);  // Trying to loop while argument is thrown from my other class
Console.WriteLine("Continue on");
Console.ReadLine();

My separate values classes Input method:

public static string Input(string input)
{
    string convert = input;

    if (convert == "Meters")
    {
        input = "Meters";
    }
    else if (convert == "Feet")
    {
        input = "Feet";
    }
    else if (convert == "Yards")
    {
        input = "Yards";
    }
    else 
    {
        throw new System.ArgumentException("Incorrect conversion");
        //Trying to loop my main program if an ArgumentException is thrown here
    }

    return input;
}

What I've attempted:

} while (convert != "Meters" || convert != "Feet" || convert != "Yards"); 

Console.WriteLine("Continue on");
Console.ReadLine();

I've tried telling it to keep looping while convert is not Meters, Feet or Yards, but after the argument is thrown I am unable to continue the program.

Would I be able to continue my application after throwing this System.ArgumentException and if so what would I input into my while loop to allow this?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Grant
  • 33
  • 3
  • 1
    A little side note: `Console.ReadLine` already returns a string. There's no need to call `Convert.ToString` on the value that's returned. (In fact, `Convert.ToString` will convert `null` to `""`, which will preclude you from detecting end of input, e.g. if stdin is redirected.) – madreflection Mar 31 '20 at 23:18

2 Answers2

3

The problem is that the position where you call Values.Input() is outside the try/catch statement and when this throws an exception, it is not handled in the catch you've defined. So it will be caught up the callstack. Try placing the Values.Input(..) inside the try/catch statement.

string convert = "";
do
{
    Console.Clear();
    Console.WriteLine("What conversion: Feet, Meters, Yards");

    try
    {
        convert = Convert.ToString(Console.ReadLine());
        // -------  PASTE
        convert = Values.Input(convert);
        Console.WriteLine(convert);
        // -----
    }
    catch (Exception)
    {
        Console.Clear();
        Console.WriteLine("Incorrect conversion");
    }

    // XXXXXXXXX CUT
    // XXXXXXXXX
    Console.ReadKey();

} while (_____); //Trying to loop while argument is thrown from my other class
Console.WriteLine("Continue on");
Console.ReadLine();
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Jeroen van Langen
  • 21,446
  • 3
  • 42
  • 57
1

This Input() function is pretty wild. What exactly is it doing? Basically nothing. You want to return some determinate value that indicates what type of unit it is, right?

Let's replace it with this:

public enum Unit { Meters, Feet, Yards }

public static Unit Input(string input)
{
    switch (input.ToLowerInvariant())
        case "meters": return Unit.Meters;
        case "feet": return Unit.Feet;
        case "yards": return Unit.Yards;
        default: throw new System.ArgumentException("Incorrect conversion");
    }
 }

So after that we can fix the code:

Unit unit;
while (true)
{    
    Console.WriteLine("What conversion: Feet, Meters, Yards");

    try
    {
        var input = Console.ReadLine();
        unit = Values.Input(convert);
        break; // if we get here we didn't throw an exception, so we can exit the loop
    }
    catch
    {
        Console.WriteLine("Incorrect conversion");
    }
}

Console.WriteLine("Continue on");
Console.ReadLine();
Jon Grant
  • 11,369
  • 2
  • 37
  • 58
  • I'll be sure to take consideration into this for any other similar projects, just a question: what is the (input.ToLowerInvariant() line doing? (I'm assuming it's just converting from uppercase to lowercase? but from what I know that would be just .ToLower() right?) – Grant Mar 31 '20 at 23:46
  • Yes, it's converting to lowercase, but you should always consider the character set of the input. Here is a good question that will help explain: https://stackoverflow.com/questions/6225808/string-tolower-and-string-tolowerinvariant – Jon Grant Mar 31 '20 at 23:51