How to properly do Exception Handling with try and catch using C# - c#

I am trying to include an exception handling in to this small sample of code. When I am prompted to input the conversionType, I tried to input strings which are supposed to trigger the catch code and print out the error message, but instead the code just shuts down like any other errors, suggesting that the error was not caught by the try catch blocks. I am still learning how exception handling works in C#. So is there anyway to correctly catch the exception and prevent the code from crashing?
static void Main(string[] args)
{
int conversionType;
double number;
Console.WriteLine("Choose the type of conversion:\n" +
"1.Celsius to Fahrenheit\n" +
"2.Fahrenheit to Celsius");
try
{
conversionType = Convert.ToInt32(Console.ReadLine());
if (conversionType == 1)
{
Console.WriteLine("Enter the Temperature in Celsius: ");
number = Convert.ToDouble(Console.ReadLine());
number = number * 9 / 5 + 32;
Console.WriteLine("Temperature in Fahrenheit: {0:00.0}°F", number);
}
else if (conversionType == 2)
{
Console.WriteLine("Enter the Temperature in Fahrenheit: ");
number = Convert.ToDouble(Console.ReadLine());
number = (number - 32) * 5 / 9;
Console.WriteLine("Temperature in Celsius: {0:00.0}°C", number);
}
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}

You shouldn't use exceptions for this, you have functions like int.TryParse and double.TryParse that return a boolean signifying whether or not they succeeded.

You should put a Console.ReadLine(); on the end of the code for you to see the exception.
And Also, you can add the code below inside your try statement just to make sure the program will catch every exception.
int conversionType;
double number;
Console.WriteLine("Choose the type of conversion:\n" +
"1.Celsius to Fahrenheit\n" +
"2.Fahrenheit to Celsius");

I think what you wanna do is multiple usage of the function within a loop.
You can catch different exception types like this and add a finally block.
static void Main(string[] args)
{
int conversionType;
double number;
do
{
try
{
Console.WriteLine("Choose the type of conversion:\n" +
"1.Celsius to Fahrenheit\n" +
"2.Fahrenheit to Celsius");
conversionType = Convert.ToInt32(Console.ReadLine());
if (conversionType == 1)
{
Console.WriteLine("Enter the Temperature in Celsius: ");
number = Convert.ToDouble(Console.ReadLine());
number = number * 9 / 5 + 32;
Console.WriteLine("Temperature in Fahrenheit: {0:00.0}°F", number);
}
else if (conversionType == 2)
{
Console.WriteLine("Enter the Temperature in Fahrenheit: ");
number = Convert.ToDouble(Console.ReadLine());
number = (number - 32) * 5 / 9;
Console.WriteLine("Temperature in Celsius: {0:00.0}°C", number);
}
}
catch (FormatException fe)
{
Console.WriteLine("Format exception:" + fe.Message);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
// do something additional for all cases
Console.WriteLine("Try again? (Y/N): ");
}
}
while (Console.ReadLine().ToUpper() == "Y");
}

Related

Infinite Loop C# Fix Please

Console.WriteLine("Mortgage Loan Calculator");
Console.WriteLine("------------------------------------");
C1 c1 = new C1();
while (true)
{
bool continueLoop = true;
do
{
try
{
Console.WriteLine("Enter loan amount: ");
loanAmount = Convert.ToDouble(Console.ReadLine());
checkLoanAmount(loanAmount);
continueLoop = false;
}
catch (FormatException formatException)
{
Console.WriteLine("\n" + formatException.Message);
Console.WriteLine("Please enter a double value. \n");
continueLoop = true;
}
catch (MyRangeException negativeNumberException)
{
Console.WriteLine("\n" + negativeNumberException.test);
}
catch (Exception exception)
{
Console.WriteLine("\n" + exception.Message);
Console.WriteLine("Input string was not in a correct format");
continueLoop = true;
}
} while (continueLoop);
do
{
try
{
Console.WriteLine("Enter loan amount: ");
years = Convert.ToDouble(Console.ReadLine());
checkLoanYears(years);
}
catch (FormatException formatException)
{
Console.WriteLine("\n" + formatException.Message);
Console.WriteLine("Please enter a double value. \n");
}
catch (MyRangeException negativeNumberException)
{
Console.WriteLine("\n" + negativeNumberException.Message);
}
catch (Exception exception)
{
Console.WriteLine("\n" + exception.Message);
Console.WriteLine("Input string was not in a correct format");
}
} while (continueLoop);
do
{
try
{
Console.WriteLine("Enter loan amount: ");
interest = Convert.ToDouble(Console.ReadLine());
checkLoanInterest(interest);
}
catch (FormatException formatException)
{
Console.WriteLine("\n" + formatException.Message);
Console.WriteLine("Please enter a double value. \n");
}
catch (MyRangeException negativeNumberException)
{
Console.WriteLine("\n" + negativeNumberException.Message);
}
catch (Exception exception)
{
Console.WriteLine("\n" + exception.Message);
Console.WriteLine("Input string was not in a correct format");
}
} while (continueLoop);
}
So I'm trying to create a Loan Program with exception handling. I have the code working to where it takes the exceptions when I input in the wrong format. The problem that I'm having though is that it keeps it in an infinite loop asking for the loan amount instead of going to the next question. If anyone could give me some advice of what I'm doing wrong that would be greatly appreciated!
Here is a partial list of things I see with your code:
Class C1 does nothing and it is not used
Outer while loop has no exit condition while(true) { } and no break; statement inside.
Repeating (copy/paste) code for similar functionality to receive user inputs. Major clue when you see this pull the code in a function, and use a loop if necessary to call the function. Here I think you use need to manualy call the function three times.
Using try{} catch{} as part of regular code instead of only for something actually un-expected. This is the reason C# has the int.TryParse(), float.TryParse() and decimal.TryParse() method, in order to branch your code depending if the input is valid or not
if(float.TryParse(input, out var value))
{
// use float `value`
} else {
// invalid input
}
Exceptions are for, well, exceptional events. Nothing in a user input program like this should be exceptional.
Your code for the loanAmount seems to be right though. It's setting continueLoop = false; and that should allow the loop to exit. You haven't shown us checkLoanAmount (which should be named CheckLoanAmount) so I can't tell you if that's causing your problem.
In any case, here's how I would do this kind of app:
Console.WriteLine("Mortgage Loan Calculator");
Console.WriteLine("------------------------------------");
decimal ReadDecimal(string message, Func<decimal, bool> validator, string validation)
{
while (true)
{
Console.WriteLine(message);
if (decimal.TryParse(Console.ReadLine(), out decimal result) && validator(result))
{
return result;
}
Console.WriteLine();
Console.WriteLine(validation);
Console.WriteLine();
}
}
decimal loanAmount = ReadDecimal("Enter loan amount: ", d => d > 0m, "Amount must be greater than zero.");
decimal years = ReadDecimal("Enter number of years: ", d => d > 0m, "Amount must be greater than zero.");
decimal interest = ReadDecimal("Enter interest rate: ", d => d >= 0m && d <= 100, "Amount must be between zero and 100.");

Restarting a program after error in catch statement

I'm trying to restart my program after I catch an error using the catch() function, but I also want it to display the error, stop the rest of the program from running, and restart the program.
This is just a shortened version of my code which I have used as an example.
using System;
namespace Calculator
{
internal class Program
{
private static void Main(string[] args)
{
float input = 0;
while (input != 5)
{
Console.Clear();
Console.WriteLine("What would you like to do? Type: 1 for Addition. Write 5 to end program.");
try
{
input = float.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("Please enter a number");
}
//Addition
if (input == 1)
{
Console.WriteLine("Enter First Value: ");
string FirstValue = Console.ReadLine();
float firstval = 0;
try
{
firstval = float.Parse(FirstValue);
}
catch (FormatException)
{
Console.WriteLine("Please enter a number");
break;
}
Console.WriteLine("Enter Second Value: ");
string SecondValue = Console.ReadLine();
float secval = 0;
try
{
secval = float.Parse(SecondValue);
}
catch (FormatException)
{
Console.WriteLine("Please enter a number");
break;
}
float sum = Add(firstval, secval);
Console.WriteLine("The sum is: {0}", sum);
}
}
}
public static float Add(float num1, float num2)
{
return num1 + num2;
}
}
}
When it says
catch (FormatException)
{
Console.WriteLine("Please enter a number");
break;
}
The break; makes it so the rest of the code stops, and it displays the error. That is good, but the program also ends after that, what I want, is that the program repeats after error. Is there any way that this could happen, but it allows 1) the Console.WriteLine("Please enter a number");, 2) the program to not run the rest of the code (The part where we are asked for a second value), and 3) the program to restart for the beginning. Please let me know if that didn't make sense, as it was a hard to explain. :)
It is very simple you do not need the "break" keyword because "break" terminates the loop execution to continue execution on exception use "continue" keyword without quotes the working fiddle is here
and your code after replacing "break" with "continue" is following
using System;
namespace Calculator
{
public class Program
{
public static void Main(string[] args)
{
float input = 0;
while (input != 5)
{
Console.Clear();
Console.WriteLine("What would you like to do? Type: 1 for Addition. Write 5 to end program.");
try
{
input = float.Parse(Console.ReadLine());
}
catch (FormatException)
{
Console.WriteLine("Please enter a number");
}
//Addition
if (input == 1)
{
Console.WriteLine("Enter First Value: ");
string FirstValue = Console.ReadLine();
float firstval = 0;
try
{
firstval = float.Parse(FirstValue);
}
catch (FormatException)
{
Console.WriteLine("Please enter a number");
continue;
}
Console.WriteLine("Enter Second Value: ");
string SecondValue = Console.ReadLine();
float secval = 0;
try
{
secval = float.Parse(SecondValue);
}
catch (FormatException)
{
Console.WriteLine("Please enter a number");
continue;
}
float sum = Add(firstval, secval);
Console.WriteLine("The sum is: {0}", sum);
}
}
}
public static float Add(float num1, float num2)
{
return num1 + num2;
}
}
}

I dont press enter but ReadLine() says I did (accidently made it that you cant answer the old one so repost)

Fixed, but now it automatically presses enter when it gets to the Main(); thing and I can't actually input anything in time. Anyone know what's wrong?
using System;
using System.Linq;
namespace Bruh
{
class Program
{
static void Main()
{
int pog = 0;
int pog2 = 0;
Random r = new Random();
Console.WriteLine("Input a whole number");
string poggers = Console.ReadLine();
if (int.TryParse(poggers, out pog))
{
pog = int.Parse(poggers);
}
else
{
Console.WriteLine("ERROR: Not a number. Please input a number and not letters.");
Console.Read();
System.Environment.Exit(1);
}
Console.WriteLine("Input a number higher than the previous");
string poggers2 = Console.ReadLine();
if (int.TryParse(poggers2, out pog2))
{
pog2 = int.Parse(poggers2);
}
else
{
Console.WriteLine("ERROR: Not a number. Please input a number and not letters.");
Console.Read();
System.Environment.Exit(1);
}
int genRand = r.Next(pog, pog2);
Console.WriteLine("This number was randomly generated between " + pog + " and " + pog2 + " and we got: " + genRand);
Console.Read();
Console.WriteLine("Would you like to try again? Y/N");
ConsoleKeyInfo answer = Console.ReadKey();
if (answer.KeyChar == 'y' || answer.KeyChar == 'Y')
{
Console.WriteLine("\n");
Main();
}
else if (answer.KeyChar == 'n' || answer.KeyChar == 'N')
{
System.Environment.Exit(1);
}
else
{
Console.WriteLine("ERROR: Y/N not any other character");
Console.Read();
System.Environment.Exit(1);
}
}
}
}
I've reworked your code into something that is more C#-like :-) - find this below.
Highlights:
You use int.TryParse() correctly, but do the conversion again
inside the true code block, using int.Parse().
No need to call System.Environment.Exit(1); to terminate the program, just let it end.
The call main() is actually a recursive call - where a method (function) calls it self. Usable sometimes, but i often leads to a StackOverflow exception. In this case, you get some strange behaviour...
using System;
namespace Bruh2
{
class Program
{
static void Main()
{
bool tryAgain = true;
while (tryAgain)
{
int pog = 0;
int pog2 = 0;
Random r = new Random();
Console.Write("Input a whole number: ");
string poggers = Console.ReadLine();
while (!int.TryParse(poggers, out pog))
{
Console.WriteLine("ERROR: Not a number. Please input a number and not letters.");
poggers = Console.ReadLine();
}
Console.Write("Input a number higher than the previous: ");
string poggers2 = Console.ReadLine();
while (!int.TryParse(poggers2, out pog2))
{
Console.WriteLine("ERROR: Not a number. Please input a number and not letters.");
poggers2 = Console.ReadLine();
}
int genRand = r.Next(pog, pog2);
Console.WriteLine("This number was randomly generated between " + pog + " and " + pog2 + " and we got: " + genRand);
Console.WriteLine();
Console.WriteLine("Would you like to try again? Y/N");
//ConsoleKeyInfo answer = Console.ReadKey();
string answer = Console.ReadKey().KeyChar.ToString().ToLower();
while (answer!="y" && answer!="n")
{
Console.WriteLine("ERROR: Y/N not any other character");
answer = Console.ReadKey().ToString().ToLower();
}
if (answer == "n")
{
tryAgain = false; // terminate the loop (and thereby the program)
}
}
}
}
}

Code is working unexpectedly in c# using visual studio code

I am a beginner in c# and I want to create a simple calculator.
I have written all the code and it is not showing any errors, however, it is not showing it correctly.
This is all the code I am using:
using System;
namespace C_
{
class Program
{
static void Main(string[] args)
{
Console.Title = "Calculator";
float num1;
float num2;
float resultSum;
float resultSub;
float resultProd;
float resultDiv;
Console.Write("Enter your first number ");
num1 = Convert.ToInt32(Console.Read());
num2 = Convert.ToInt32(Console.Read());
resultSum = num1 + num2;
Console.Write("The sum is " + resultSum);
resultSub = num1 - num2;
Console.Write("The differnce is " + resultSub);
resultProd = num1 * num2;
Console.Write("The product is " + resultProd);
resultDiv = num1 / num2;
Console.Write("The quotient is " + resultDiv);
Console.ReadKey();
}
}
}
When I run this without debugging,
the console shows this:
https://learn.microsoft.com/en-us/dotnet/api/system.console.writeline?view=netcore-3.1
If you replace Console.Write... with Console.WriteLine..., it will add line breaks to the ends of your print statements, so your output should look like:
The sum is 63
The difference is 37
...
Not sure if I would use float for the type. Especially since you are converting to int32. I have put some different techniques into your program. Since you are just learning these are good things to know. I have provided explanations in the comments of the code.
static void Main(string[] args)
{
Console.Title = "Calculator";
// No need to put the type multiple times
// Just use a comma to separate the names
int num1, num2, resultSum, resultSub, resultProd, resultDiv;
Console.WriteLine("Enter your first number:");
// This is just a label
Num1Entry:
try
{
num1 = Convert.ToInt32(Console.ReadLine());
}
// This exception is for when you don't get a number from the user. i.e. num1 = a
catch (FormatException)
{
Console.WriteLine("Not a number. Please enter a valid number.");
// This will jump your program back to the beginning of the try-catch so you can enter a valid number for num1
goto Num1Entry;
}
// This exception is for when the number is out of range for the data type. i.e. num1 = 2147483648 is too big for an int data type.
catch (OverflowException)
{
Console.WriteLine("Invalid number. Please enter a valid number.");
// This will jump your program back to the beginning of the try-catch so you can enter a valid number for num1
goto Num1Entry;
}
Console.WriteLine("Enter your second number:");
// This is just a label
Num2Entry:
try
{
num2 = Convert.ToInt32(Console.ReadLine());
}
// This exception is for when you don't get a number from the user. i.e. num2 = a
catch (FormatException)
{
Console.WriteLine("Not a number. Please enter a valid number.");
// This will jump your program back to the beginning of the try-catch so you can enter a valid number for num2
goto Num2Entry;
}
// This exception is for when the number is out of range for the data type. i.e. num2 = 2147483648 is too big for an int data type.
catch (OverflowException)
{
Console.WriteLine("Invalid number. Please enter a valid number.");
// This will jump your program back to the beginning of the try-catch so you can enter a valid number for num2
goto Num2Entry;
}
resultSum = num1 + num2;
Console.WriteLine("The sum is " + resultSum);
resultSub = num1 - num2;
Console.WriteLine("The differnce is " + resultSub);
resultProd = num1 * num2;
Console.WriteLine("The product is " + resultProd);
// if num2 = 0 you will get an exception.
// Use a try-catch to keep your program from failing.
try
{
resultDiv = num1 / num2;
Console.WriteLine("The quotient is " + resultDiv);
}
catch (DivideByZeroException)
{
Console.WriteLine("You cannot divide by 0");
}
Console.ReadKey();
}
Your code uses the consolekey values, not the numeric value that you entered. The consolekey for 2 is 50. The consolekey for return is 13.

C# How can I handle this exception?

I am new to C# and trying to create a GPA calculator using a sentinel controlled loop. To end the loop, I want the user to enter an 'x', but it is throwing an exception. I'm pretty sure it is because 'x' is not a double type, but I am not sure how I can make it work. I was using a number to exit before but it kept being added to the gradeTotal. Any suggestions would be great! Thanks!
Code:
class Program
{
static void Main(string[] args)
{
double gradeTotal = 0;
int[] score = new int[100];
string inValue;
int scoreCnt = 0;
Console.WriteLine("When entering grades, use a 0-4 scale. Remember;
A = 4, B = 3, C = 2, D = 1, F = 0");
Console.WriteLine("Enter grade {0}: ((X to exit)) ", scoreCnt + 1);
inValue = Console.ReadLine();
gradeTotal += double.Parse(inValue);//This may be a problem area
while (inValue != "x")
{
if (int.TryParse(inValue, out score[scoreCnt]) == false)
Console.WriteLine("Invalid data -" + "0 stored in array");
++scoreCnt;
Console.WriteLine("Enter Score{0}: ((X to exit)) ", scoreCnt +
1);
inValue = Console.ReadLine();
gradeTotal += double.Parse(inValue);//This is a problem area
}
Console.WriteLine("The number of scores: " + scoreCnt);
Console.WriteLine("Your GPA is: " + gradeTotal);//Obviously not the
//right calculation, just trying to figure it out
Console.ReadLine();
}
}
Least effort
Instead of
gradeTotal += double.Parse(inValue);//This is a problem area
Try
if (inValue == "X") break;
gradeTotal += double.Parse(inValue);
More robust
double d;
var ok = double.TryParse(inValue, out d);
if (!ok) break;
gradeTotal += d;
You have zero validation on the inValue before trying to parse it. That's the problem. How you resolve this is up to you. Here's a couple suggestions:
wrap the code in a try...catch...
try {
grandTotal += double.Parse(inValue);
} catch (Exception e) {
Console.WriteLine("Invalid input!");
}
Use Regular Expressions to validate user input and return error if not a number
(System.Text.RegularExpressions.Regex)

Categories