1

I've read that using "goto" in C# is not recommended However, my code uses goto and so far, errors appeared when trying to avoid "goto"

anum1r:
Console.Write ("What is the first number? ");
try {
    num1 = Convert.ToDouble (Console.ReadLine ());
} catch (System.FormatException) {
    Console.Beep ();
    Console.WriteLine ("");
    Console.WriteLine ("You have entered an invalid number!");
    Console.WriteLine ("");
    goto anum1r;
}
anum2r:
Console.Write ("What is the second number? ");
try {
    num2 = Convert.ToDouble (Console.ReadLine ());
} catch (System.FormatException) {
    Console.Beep ();
    Console.WriteLine ("");
    Console.WriteLine ("You have entered an invalid number!");
    Console.WriteLine ("");
    goto anum2r;
}
answer = num1 + num2;

How do I transform this code without using GOTO. ty

  • You should refactor your code to extrapolate the common code into a function, and then call the function within a try-catch block which handles errors. I'd recommend reading a few books on basic programming first. – Kif Jun 18 '15 at 10:39
  • It isn't so. Goto statements should be used where they belong it will be erroneous only if it is used at the wrong place. Do not go believe such recommendations. See: http://meyerweb.com/eric/comment/chech.html – Identity1 Jun 18 '15 at 10:39
  • @Identity1 I agree goto may not be always bad, some (very rare) times it may be a better solution than something else. Points here (in this question) IMO are: 1) goto is useless (it just decrease readability and make program longer), 2) code itself is prolix and not reusable, it's asking for refactoring, 3) this use of exceptions is _wrong_, you do not need exception handling at all – Adriano Repetti Jun 18 '15 at 11:24

8 Answers8

2

Use a while loop:

double num1;
while (true) {
    Console.Write ("What is the first number? ");
    try {
        num1 = Convert.ToDouble (Console.ReadLine ());
        break;
    } catch (System.FormatException) {
        Console.Beep ();
        Console.WriteLine ("");
        Console.WriteLine ("You have entered an invalid number!");
        Console.WriteLine ("");
    }
}

As you need this code twice, it is also a good idea to refactor it in a separate method like @James' answer. (Though it needs an extra parameter to modify the user prompt.)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
0

You could use a while loop

private double? GetNumber()
{
    double? result = null;
    try {
        result = Convert.ToDouble (Console.ReadLine ());
    } catch (System.FormatException) {
        Console.Beep ();
        Console.WriteLine ("");
        Console.WriteLine ("You have entered an invalid number!");
        Console.WriteLine ("");
    }
    return result;
}

...
// prompt for first number
double? num1 = null;
while (!num1.HasValue)
{
   Console.Write ("What is the first number? ");
   num1 = GetNumber();
}
// prompt for second number
double? num2 = null;
while (!num2.HasValue)
{
   Console.Write ("What is the second number? ");
   num2 = GetNumber();
}
// calculate result
answer = num1.Value + num2.Value;
James
  • 80,725
  • 18
  • 167
  • 237
0

You can use a for-loop and a collection like a double[], also use double.TryParse:

int numbers = 10;
double[] allNumbers = new double[numbers];
for (int i = 0; i < numbers; i++)
{
    Console.Write("What is the {0}. number? ", i + 1);
    double num;
    if (double.TryParse(Console.ReadLine().Trim(), out num))
    {
        allNumbers[i] = num;
    }
    else
    {
        i--; // ask the user until we have the numbers
        Console.Beep();
        Console.WriteLine("");
        Console.WriteLine("You have entered an invalid number!");
        Console.WriteLine("");
    }
}
double answer = allNumbers.Sum(); // LINQ so add using System.Linq;

Another way is to extract a method for this purpose:

private static double? ReadNumberFromConsole()
{
    double num;
    if (double.TryParse(Console.ReadLine().Trim(), out num))
        return num;
    else
        return null;
}

That makes the code more readable:

for (int i = 0; i < numbers; i++)
{
    Console.Write("What is the {0}. number? ", i + 1);
    double? num = ReadNumberFromConsole();
    if (num.HasValue)
    {
        allNumbers[i] = num.Value;
    }
    else
    {
        i--; // ask the user until we have the numbers
        Console.Beep();
        Console.WriteLine("");
        Console.WriteLine("You have entered an invalid number!");
        Console.WriteLine("");
    }
}
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
0

You MAY simply use a loop:

double PromptForNumber(string message) {
    while (true) {
        Console.Write(message + " ");
        try {
            return Convert.ToDouble(Console.ReadLine());
        } catch (FormatException) {
            Console.Beep();
            Console.WriteLine();
            Console.WriteLine("You have entered an invalid number!");
            Console.WriteLine();
        }
    }
}

Used as:

double num1 = PromptForNumber("What is the first number?");
double num2 = PromptForNumber("What is the second number?");

BUT here you're also using exceptions where they're not necessary. Invalid user input is not exceptional and there are better ways to handle that:

double PromptForNumber(string message) {
    while (true) {
        Console.Write(message + " ");

        double number;
        if (Double.TryParse(Console.ReadLine(), out number))
            return number;

        Console.Beep();
        Console.WriteLine("\nYou have entered an invalid number!\n");
    }
}

Note that this way you'll also handle OverflowException that you left out in your original code.

Do you need 100 inputs? One line of code:

var inputs = Enumerable.Range(1, 100)
    .Select(x => PromptForNumber(String.Format("Enter number #{0}:", x)));
Adriano Repetti
  • 65,416
  • 20
  • 137
  • 208
0

There are two good ways to improve your code:

  1. Extract into a separate method the logic for repeatedly asking the user for a number until they enter a valid one. (Use a loop construct to handle looping rather than a goto.)
  2. Use double.TryParse() to avoid having to catch a format exception.

If you put both of those together, you get code that looks something like this:

using System;

namespace Demo
{
    public static class Program
    {
        private static void Main()
        {
            double first = askForNumber("What is the first number? ");
            Console.WriteLine();
            double second = askForNumber("What is the second number? ");

            Console.WriteLine("\nYou entered {0} and {1}", first, second);
        }

        private static double askForNumber(string prompt)
        {
            while (true)
            {
                Console.Write(prompt);
                double result;

                if (double.TryParse(Console.ReadLine(), out result))
                    return result;

                Console.Beep();
                Console.WriteLine("\nYou have entered an invalid number!\n");
            }
        }
    }
}
Matthew Watson
  • 104,400
  • 10
  • 158
  • 276
0

I would also highly recommend avoid using Convert.ToDouble on user input. Using exceptions as an input validating system is wrong on every level.

Use something like this instead:

double GetNumberFromUser() {
    double Num = double.NaN;
    while(!double.tryParse(Console.ReadLine(), out Num) && !double.IsNaN(Num))
    {
        Console.Beep();
        Console.WriteLine("");
        Console.WriteLine("You have entered an invalid number!");
        Console.WriteLine("");
    }
    return Num;
}

why test for IsNaN also? read this.

Community
  • 1
  • 1
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
-1
private Double InputNum1
{
    Console.Write ("What is the first number? ");
    try 
    {
        num1 = Convert.ToDouble (Console.ReadLine ());
        return num1;
    } 
    catch (System.FormatException) 
    {
        Console.Beep ();
        Console.WriteLine ("");
        Console.WriteLine ("You have entered an invalid number!");
        Console.WriteLine ("");
        InputNum1();
    }
}
Ankit
  • 672
  • 6
  • 18
  • A similar function could be used for 2nd number - say InputNum2(). – Ankit Jun 18 '15 at 10:42
  • How are you going to sum the numbers? – Sybren Jun 18 '15 at 10:44
  • @Sybren: Its simple. Add a return type. Function invoking InputNum1() & InputNum2() would get these values & it could be added there. P.S: Just the line of code that I missed, where addition is being done. – Ankit Jun 18 '15 at 11:06
-2

you can use a while to query for numbers until they are valid:

double? num1 = null;
while (num1==null){
   Console.Write ("What is the first number? ");
   try {
       num1 = Convert.ToDouble (Console.ReadLine ());
   } catch (System.FormatException) {
       Console.Beep ();
       Console.WriteLine ("");
       Console.WriteLine ("You have entered an invalid number!");
       Console.WriteLine ("");
   }
}
dognose
  • 20,360
  • 9
  • 61
  • 107