Catching an input error - c#

I have this assignment for school where we have to use try and catch in order to ensure that the user doesn't input a negative number of donuts and data that is not an integer. I got the try/catch to work so that it asks for the number of donuts again when I enter a negative number, but when I enter a letter instead of a number for the number of donuts it comes up with the error message I created for it but doesn't give the option to enter the amount of donuts again. If someone could help me that would be greatly appreciated. Thanks. Here's what I got for my code:
using System;
public class CostofDonuts
{
public static void Main()
{
string lastName;
int number_Of_Donuts;
double Total_Cost, Final_Cost;
try
{
// Get user to input their last name
Console.Write("Enter customer's last name -> ");
lastName = Convert.ToString(Console.ReadLine());
//Get user to input amount of donuts purchased. Ensure that the integer inputted is positive.
do
{
Console.Write("Enter the amount of donuts purchased -> ");
number_Of_Donuts = Convert.ToInt32(Console.ReadLine());
if (number_Of_Donuts < 0)
Console.WriteLine("Invalid input, number of donuts must be positive");
} while (number_Of_Donuts <= 0);
//Calculate cost of donuts
if (number_Of_Donuts < 6)
Total_Cost = number_Of_Donuts * 0.5;
if (number_Of_Donuts <= 15)
Total_Cost = number_Of_Donuts * 0.4;
else
Total_Cost = number_Of_Donuts * 0.3;
//Calculate cost with tax
if (number_Of_Donuts < 12)
Final_Cost = (Total_Cost + 0.25) * 1.13;
else
Final_Cost = Total_Cost + 0.25;
// Output final results
Console.WriteLine("{0} bought {1} donuts which came to a total of {2:C}", lastName, number_Of_Donuts, Final_Cost);
Console.ReadLine();
}
catch (FormatException e)
{
Console.WriteLine("Input must be a positive integer");
}
catch (Exception e)
{
Console.WriteLine("Input must be a positive integer");
}
}
}

You need to use try / catch inside of your loop in order to keep continue:
do
{
Console.Write("Enter the amount of donuts purchased -> ");
try
{
number_Of_Donuts = Convert.ToInt32(Console.ReadLine());
}
catch (Exception)
{
Console.WriteLine("Invalid input, number of donuts must be positive");
number_Of_Donuts = 0;
}
} while (number_Of_Donuts <= 0);

you can use int.TryParse
do
{
Console.Write("Enter the amount of donuts purchased -> ");
if(int.TryParse(Console.ReadLine(), out number_Of_Donuts ) && number_Of_Donuts >= 0)
break;
Console.WriteLine("Invalid input, number of donuts must be positive");
} while (number_Of_Donuts <= 0);

do
{
Console.Write("Enter the amount of donuts purchased -> ");
Int.TryParse(Console.ReadLine(), out number_Of_Donuts);
if (number_Of_Donuts < 0)
Console.WriteLine("Invalid input, number of donuts must be positive");
} while (number_Of_Donuts <= 0);

Related

Validating input value from console without exiting loop C#

Lets say for a console application, I want the user to enter how many dices he would like to throw. Onlu values 1-5 will be accepted. I tried doing this:
Console.WriteLine("How many dices would you like to throw?");
int amount = Convert.ToInt32(Console.ReadLine());
while(true)
{
if(amount < 1 || amount > 5)
{
Console.WriteLine("Please enter a value between 1-5");
break;
}
}
The problem here is that if the user enters an invalid number, the program stops. I want it to simply continue asking until correct value is inputed. Any ideas?
cheers.
I haven't tested it but slightly refactored your code as below, it should do what you want:
Console.WriteLine("How many dices would you like to throw?");
int amount = Convert.ToInt32(Console.ReadLine());
while(amount < 1 || amount > 5)
{
Console.WriteLine("Please enter a value between 1-5");
amount = Convert.ToInt32(Console.ReadLine());
}
EDIT: if you want to safely check whether it is an integer value, you can use the below version of code:
Console.WriteLine("How many dices would you like to throw?");
var input = Console.ReadLine();
while(!int.TryParse(input, out int amount) || amount < 1 || amount > 5)
{
Console.WriteLine("Please enter a value between 1-5");
input = Console.ReadLine();
}
You might want to check if the entered value is actually an integer.
int amount;
Console.WriteLine("How many dices would you like to throw?");
do
{
if (int.TryParse(Console.ReadLine(), out var i))
{
if (i >= 1 && i <= 5)
{
amount = i;
break;
}
Console.WriteLine("The integer value is not between 1 and 5");
}
{
Console.WriteLine("The value you entered is not an integer");
}
} while (true);
EDIT
I generally like to give the user the option to exit completely.
int amount;
Console.WriteLine("How many dices would you like to throw? Or enter 'X' to exit.");
do
{
var input = Console.ReadLine();
if(input.Equals("X", StringComparison.InvariantCultureIgnoreCase))
{
return;
}
if (int.TryParse(input, out var i))
{
if (i >= 1 && i <= 5)
{
amount = i;
break;
}
Console.WriteLine("The integer value is not between 1 and 5");
}
{
Console.WriteLine("The value you entered is not an integer");
}
} while (true);

C# Sharp Grade program using for and while

I'm new at C# and am having trouble with nested loops. I'm working on a Grading program with a menu. The first menu asks the user how many grades would they like to enter. Then, the user enters the grades. The Second menu figures out the average and grade. I'm having trouble with a nested loop where it would ask you a given number of time to enter grades.
Once that is done, I'm also having trouble with how I would pass that info to the second menu to get the average. I done something like this better in Java, but there we had a set number of grades; then, we made a variable for each grade. Finally we summed them and divided by a set number.
bool exit = false;
do
{
Console.WriteLine("1. Enter Grades");
Console.WriteLine("2. Get Average");
Console.WriteLine("3. My program");
Console.WriteLine("4. exit");
string input = Console.ReadLine();
Console.WriteLine("");
if (input == "1")
{
int totalGrades = 0;
double grades;
double grade, finalGrade = 0;
//User Input
Console.WriteLine("How many grades do you want to enter? ");
//While loop for TryParse
while(!int.TryParse(Console.ReadLine(),out totalGrades))
{
Console.WriteLine("Please enter a valid number");
}
while (totalGrades < 1)
{
Console.WriteLine("Enter Grade: ");
string input = Console.ReadLine();
for (int i = 0; i<= totalGrades; totalGrades++)
Console.WriteLine(totalGrades);
}
Console.ReadLine();
}
else if (input == "2")
{
double average = 0;
if (average >= 90)
{
Console.WriteLine($"The average is a {average} which is an A.");
}
else if (average >= 80)
{
Console.WriteLine($"The average is a {average} which is an B.");
}
else if (average >= 70)
{
Console.WriteLine($"The average is a {average} which is an C.");
}
else if (average >= 60)
{
Console.WriteLine($"The average is a {average} which is an D.");
}
else
{
Console.WriteLine($"The average is a {average} which is an E.");
}
}
else
{
exit = true;
}
}
while (exit == false);
I've changed a few things in order to make the code easier to understand.
private static void Main(string[] args)
{
ProgramLoop();
}
private static void ProgramLoop()
{
var grades = new List<double>();
double average;
var exit = false;
do
{
System.Console.WriteLine("1. Enter Grades");
System.Console.WriteLine("2. Get Average");
System.Console.WriteLine("3. My program");
System.Console.WriteLine("4. exit");
var input = System.Console.ReadLine();
System.Console.WriteLine("");
switch (input)
{
case "1":
grades = EnterGrades();
break;
case "2":
average = GetAverage(grades);
break;
case "3":
MyProgram();
break;
case "4":
exit = true;
break;
default:
System.Console.WriteLine($"'{input}' is not a valid choice.");
break;
}
}
while (exit == false);
}
private static List<double> EnterGrades()
{
int numberOfGrades = 0;
var grades = new List<double>();
System.Console.WriteLine("How many grades do you want to enter? ");
// Read number of grades
while (!int.TryParse(System.Console.ReadLine(), out numberOfGrades) || numberOfGrades < 1)
{
System.Console.WriteLine("Please enter a valid number");
}
while (grades.Count != numberOfGrades)
{
// Read grade
System.Console.WriteLine("Enter Grade: ");
double grade;
while (!double.TryParse(System.Console.ReadLine(), out grade) || grade < 0 || grade > 100)
{
System.Console.WriteLine("Please enter a valid grade between 0.0 and 100.0");
}
grades.Add(grade);
}
return grades;
}
private static double GetAverage(IList<double> grades)
{
var average = grades.Average();
if (average >= 90)
{
System.Console.WriteLine($"The average is {average}, which is an A.");
}
else if (average >= 80)
{
System.Console.WriteLine($"The average is {average}, which is an B.");
}
else if (average >= 70)
{
System.Console.WriteLine($"The average is {average}, which is an C.");
}
else if (average >= 60)
{
System.Console.WriteLine($"The average is {average}, which is an D.");
}
else
{
System.Console.WriteLine($"The average is {average}, which is an E.");
}
return average;
}
I would recommend you to split your code into methods. The code will be easier to understand, and it's a great practice to not cram too much code together.
If you plan on adding more functionality and write more code, I would also recommend you to look into how you can apply object oriented programming to this, i.e. writing classes like a GradeCard.
So there are a couple things I'd like to highlight and I also added notes to the code. You want to keep 2 variables throughout your program/method to keep track of everything entered. They are the 2 pieces of average (1) Total and (2) Count of input numbers. See the code and read it line by line and see the comments. Hope this helps you. Feel free to ask questions if something doesn't make sense.
bool exit = false;
// added variables outside of loop so they are available everywhere in the method
double grades = 0;
int gradesCount = 0;
do
{
Console.WriteLine("1. Enter Grades");
Console.WriteLine("2. Get Average");
Console.WriteLine("3. exit");
string input = Console.ReadLine();
Console.WriteLine("");
if (input == "1")
{
int totalGrades = 0;
//User Input
Console.WriteLine("How many grades do you want to enter? ");
//While loop for TryParse
while (!int.TryParse(Console.ReadLine(), out totalGrades))
{
Console.WriteLine("Please enter a valid number");
}
// increment the count of grades by the number of grades the user wants to add
gradesCount += totalGrades;
// variable to keep a count and avoid infinite loop
int addedGradesCount = 0;
// while loop works like a for loop using our variable to keep count of grades we add
while (addedGradesCount < totalGrades)
{
Console.WriteLine("Enter Grade: ");
// variable to store entered grade
double newGrade = 0;
//Reusing code from while loop above for TryParse
while (!double.TryParse(Console.ReadLine(), out newGrade))
{
Console.WriteLine("Please enter a valid number");
}
// increment running total of grades with the user input number
grades += newGrade;
// output to user - got rid of loop through totalGrades
Console.WriteLine("You entered: " + newGrade + " - Total: " + grades);
// increment variable to keep count! if this is not here, you will have infinite loop
addedGradesCount++;
}
// Console.ReadLine(); // not needed
}
else if (input == "2")
{
// calculate average using the method variables we initialized at the beginning
double average = (grades / gradesCount);
if (average >= 90)
{
Console.WriteLine($"The average is a {average} which is an A.");
}
else if (average >= 80)
{
Console.WriteLine($"The average is a {average} which is an B.");
}
else if (average >= 70)
{
Console.WriteLine($"The average is a {average} which is an C.");
}
else if (average >= 60)
{
Console.WriteLine($"The average is a {average} which is an D.");
}
else
{
Console.WriteLine($"The average is a {average} which is an E.");
}
}
else
{
exit = true;
}
} while (exit == false);
Console.ReadKey();
this seems to work
static void Main(string[] args)
{
bool exit = false;
List<float> grades = new List<float>();
do
{
Console.WriteLine("1. Enter Grades");
Console.WriteLine("2. Get Average");
Console.WriteLine("3. My program");
Console.WriteLine("4. exit");
Console.WriteLine("");
string input = Console.ReadLine();
Console.WriteLine("");
if (input == "1")
{
int totalGrades = 0;
//User Input
Console.WriteLine("How many grades do you want to enter? ");
while (true)
{
try
{
totalGrades = Convert.ToInt32(Console.ReadLine());
break;
}
catch (FormatException)
{
Console.WriteLine("This is not a valid number");
continue;
}
}
Console.WriteLine("");
while (totalGrades > 0)
{
while (true)
{
try
{
grades.Add(Convert.ToInt32(Console.ReadLine()));
totalGrades--;
break;
}
catch (FormatException)
{
Console.WriteLine("This is not a valid number");
continue;
}
}
}
Console.WriteLine("");
}
else if (input == "2")
{
double average = grades.Average();
if (average >= 90)
{
Console.WriteLine($"The average is a {average} which is an A.");
}
else if (average >= 80)
{
Console.WriteLine($"The average is a {average} which is an B.");
}
else if (average >= 70)
{
Console.WriteLine($"The average is a {average} which is an C.");
}
else if (average >= 60)
{
Console.WriteLine($"The average is a {average} which is an D.");
}
else
{
Console.WriteLine($"The average is a {average} which is an E.");
}
Console.WriteLine("");
}
else if (input == "4")
{
exit = true;
} else
{
Console.WriteLine("This is not an option");
}
}
while (exit == false);
}

My try isn't catching my error messages,,,

When I run my code I can enter any character and it gives me a letter grade back, which it isn't supposed to. What am I missing?
namespace ProjException
/* Include exception handling techniques with the traditional averaging program.
* Allow the user to input multiple sets of scores.
* Ensure that only numeric values are entered and that values fall between 0 and 100.
* Calculate the average for each set of values.
* Test the result to determine whether an A, B, C, D, or F should be recorded. The scoring rubric is as follows: A—90–100; B—80–89; C—70–79; D—60–69; F < 60.
* Your solution should include exception-handling techniques with a minimum of three appropriate catch clauses.
*/
{
class Program
{
static void Main(string[] args)
{
// Variables Declared
int grade = 0;
int total = 0;
int count = 0;
double average;
string letterGrade = "F";
while (grade != -99)
{
try
{
Console.Write("Enter a Grade 0-100 -99 to quit: ");
grade = int.Parse(Console.ReadLine());
if ((grade != -99 && grade < 0) || grade > 100)
throw new ArgumentOutOfRangeException();
if (grade != -99)
{
total += grade;
count++;
}
}
catch (FormatException e)
{
Console.WriteLine("Grade must be a number");
}
catch (ArgumentOutOfRangeException e)
{
Console.WriteLine("Grade must be between 0 and 100 or -99 to quit");
}
catch (Exception e)
{
Console.WriteLine("Some other error occurred");
Console.WriteLine(e);
}
average = (double)total / count;
if (average >= 90)
letterGrade = "A";
else if (average >= 80)
letterGrade = "B";
else if (average >= 70)
letterGrade = "C";
else if (average >= 60)
letterGrade = "D";
else
letterGrade = "F";
Console.WriteLine("Your letter grade is " + letterGrade);
Console.ReadKey();
}
}
}
}
You don't change the flow, when you catch an exception (which works fine). The program will continue after your try catch-blocks and eventually reach the output of the grade. One way here is to use continue in the catch blocks, to cause the loop to end the current iteration and start the next from the beginning.

How to force the console to only accept a number within a certain range?

I have this code where I input a name, and then an integer. The application will then repeat the name entered according to the integer specified. The issue i'm having is, I only want the user to be able to repeat the name a max of 10 times and and min of 1. Here is what i have thus far.
Console.Write("PLEASE ENTER YOUR FIRST AND LAST NAME: ");
string Name = Console.ReadLine();
Console.Write("Enter the number of times you wish for me to repeat your name, " + Name );
int number = Int32.Parse(Console.ReadLine());
for (int i = 0; i < number; i++)
Console.WriteLine(""+ Name);
Console.ReadKey();
EDIT: If someone sees an easier way of doing what I have, I would be happy to suggestions!
You need to filter and validate if the input number is minimum of 1, and maximum of 10, before printing the names. You can do this:
Console.Write("PLEASE ENTER YOUR FIRST AND LAST NAME: ");
string Name = Console.ReadLine();
Console.Write("Enter the number of times you wish for me to repeat your name, " + Name);
int number = 0;
do
{
Int32.TryParse(Console.ReadLine(), out number);
if (number > 10 || number < 1)
Console.WriteLine("Please input numbers between 1 to 10");
} while (number > 10 || number < 1);
for (int i = 0; i < number; i++)
Console.WriteLine("" + Name);
Console.ReadKey();
I am doing a do-while loop here. Unless the while loop is satisfied, it will continuously verify if the number is on the range specified or else it will exit and it will print the names.
static void Main(string[] args)
{
Console.Write("PLEASE ENTER YOUR FIRST AND LAST NAME: ");
string Name = Console.ReadLine();
Console.Write("Enter the number of times you wish for me to repeat your name");
var input = Console.ReadLine();
int number = -1;
while (!int.TryParse(input, out number)) {
Console.WriteLine("Incorrect Value");
Console.Write("Enter the number of times you wish for me to repeat your name");
input = Console.ReadLine();
}
for (int i = 0; i < number; i++)
{
Console.WriteLine("" + Name);
if (i == 9)
{
Console.WriteLine("End Program");
break;
}
}
Console.ReadKey();
}
You could wrap the ReadLine() in a while statement
Example being
int number = -1;
while(number < 1 || number > 10)
{
//Input code
}
//for loop goes under here

Using "if" statement to remove min/max user input data

I'm new to C#, well, coding in general.
I have done fairly well by myself to date, in this introduction course I am taking, but I ran into a road bump.
I am trying to figure out how to code a if statement that will run inside a loop to analyze 5 different ints as they are entered and to put the max int and min int seperatly so that I can ue the remaining three ints to make a calculation.
To be exact, validate user input and remove the min/max user input to average the remaining three.
PS, I tried an array but for some reason it wasn't working well. I don't have the code as I'm at work right now though. I was told in a lecture that an if statement should be used but arrays are possible too.
Thank you for your time and any possible answers.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string userIsFinished = "";
string name, city, value;
double rating, avg = 0;
double[] array1 = new double[5];
double max = 0;
double min = double.MaxValue;
double score, totalScore = 0;
//get basic information
do
{
Console.WriteLine("Please enter divers name.");
name = Console.ReadLine();
Console.WriteLine("Please enter the divers city.");
city = Console.ReadLine();
//get and validate user input for 1 dive rating
Console.WriteLine("Please enter a dive rating between 1.00 and 1.67.");
rating = Double.Parse(Console.ReadLine());
while (rating < 1 || rating > 1.69)
{
Console.WriteLine("Oops, you entered an invalid number. Please, enter a dive rating between 1.00 and 1.67.");
rating = Double.Parse(Console.ReadLine());
}
Console.ReadLine();
// get and validate user input for 5 judge scores
for (int s = 1; s <= 5; s++)
{
Console.WriteLine("Please enter the score for judge {0}.", s);
value = Console.ReadLine();
score = Convert.ToDouble(value);
while (score < 0 || score > 10)
{
Console.WriteLine("Invalid entry, please enter a number in between 0 - 10.");
score = Convert.ToDouble(Console.ReadLine());
}
array1[s] = Convert.ToDouble(score); //----this line keeps throwing an exception
}
Console.ReadLine();
//calculate totalScore by dropping min/max scores and averaging them times dive rating
foreach (int i in array1)
{
if (i > max)
max = i;
if (i < min)
min = i;
avg += i;
}
totalScore = avg * rating;
//Print gathered and calculated information
Console.WriteLine("Divers name: {0}", name);
Console.WriteLine("Divers city: {0}", city);
Console.WriteLine("Dive degree of difficulty: {0}", rating);
Console.WriteLine("Total dive score is: {0}", totalScore);
// Ask if user wants to process another diver and continue or exit program
Console.WriteLine("Would you like to enter another divers information? [Y]es [N]o: ");
userIsFinished = Console.ReadLine();
}
while
(userIsFinished.ToLower() != "n");
Console.ReadLine();
}
}
}
or you can go list route and
List<int> apples = new List<int>();
apples.Add(31);
apples.Add(34);
apples.Add(100);
apples.Add(57);
apples.Add(1);
int min = apples.Min();
int max = apples.Max();
apples.Remove(min);
apples.Remove(max);
decimal average = (decimal)(apples.Sum()) / apples.Count;
Not sure about your question... You want to know, the max and min about 5 values, and the avarage about the three others...
int[] n = { 4, 7, 29, 3, 87 };
int max = 0;
int min = int.MaxValue;
double avg = 0;
foreach (int i in n)
{
if (i > max)
max = i;
if (i < min)
min = i;
avg += i;
}
avg = avg / n.Count - 2;
try this code:
int[] a = new int[5];
int minpos;
int maxpos;
int min = Int32.MaxValue;
int max = a[0];
int temp = 0;
for (int i = 0; i < 5; i++)
{
Console.WriteLine(" Enter number " + (i + 1));
Int32.TryParse(Console.ReadLine(), out temp);
a[i] = temp;
//Decision Making Logic
if (min > temp)
{
min = temp;
minpos = i;
}
if (max < temp)
{
max = temp;
maxpos = i;
}
}
//At the end of this loop you will see that minpos contains the index of minimum element
//and maxpos contains index of maximum element,values in remaining indeces contain elements that are neither max or min in that //collection
Thanks guys, it appears I needed a good night of sleep. Thanks a ton for all these helpful answers as I'm sure I will be delving into those methods soon and it will be good to be able to get a head start on them. Here is my code,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string userIsFinished = "";
string name, city;
double rating, avg = 0;
double max = 0;
double min = 10;
double score, value = 0, totalScore = 0, finalScore = 0;
//get basic information
do
{
Console.WriteLine("\n");
Console.WriteLine("Please enter divers name.");
name = Console.ReadLine();
Console.WriteLine("Please enter the divers city.");
city = Console.ReadLine();
//get and validate user input for 1 dive rating
Console.WriteLine("Please enter a dive rating between 1.00 and 1.67.");
rating = Double.Parse(Console.ReadLine());
while (rating < 1 || rating > 1.69)
{
Console.WriteLine("Oops, you entered an invalid number. Please, enter a dive rating between 1.00 and 1.67.");
rating = Double.Parse(Console.ReadLine());
}
Console.ReadLine();
// get and validate user input for 5 judge scores
for (int s = 1; s <= 5; s++)
{
Console.WriteLine("Please enter the score for judge {0}.", s);
score = Convert.ToDouble(Console.ReadLine());
while (score < 0 || score > 10)
{
Console.WriteLine("Invalid entry, please enter a number in between 0 - 10.");
score = Convert.ToDouble(Console.ReadLine());
}
if (score > max)
max = score;
if (score < min)
min = score;
totalScore = score + totalScore;
}
Console.ReadLine();
\\Calculate values
value = totalScore - max - min;
avg = value / 3;
finalScore = avg * rating;
//Print gathered and calculated information
Console.WriteLine("Divers name: {0}", name);
Console.WriteLine("Divers city: {0}", city);
Console.WriteLine("Dive degree of difficulty: {0}", rating);
Console.WriteLine("Total dive score is: {0}", finalScore);
Console.WriteLine("\n");
// Ask if user wants to process another diver and continue or exit program
Console.WriteLine("Would you like to enter another divers information? [Y]es [N]o: ");
userIsFinished = Console.ReadLine();
}
while
(userIsFinished.ToLower() != "n");
Console.ReadLine();
Console.WriteLine("\n");
}
}
}

Categories

Resources