C# How can I handle this exception? - c#

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)

Related

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)
}
}
}
}
}

How to properly do Exception Handling with try and catch using 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");
}

How to Make User Input into Array and Pass It to a Method in C#?

So I have this very simple program that I have created that gets the user input and then pass the values to the method named average. Everything is perfectly fine, however, something crossed my mind like "What if the user only enters two numbers or an array of numbers?". I know that I have to use array as a parameter, but somehow I am not sure how to accomplish what i want to do. Do you guys have any tips on how I can achieve what i am trying to do? My code is here:
using System;
namespace Averages
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter number(s): ");
double num1 = Convert.ToInt32(Console.ReadLine());
double num2 = Convert.ToInt32(Console.ReadLine());
double num3 = Convert.ToInt32(Console.ReadLine());
average(num1, num2, num3);
Console.ReadKey();
}
static void average(double num1, double num2, double num3)
{
double avg = (num1 + num2 + num3) / 3;
Console.WriteLine("You have entered: " + num1 + ", " + num2 + ", " + num3);
Console.WriteLine("The average is: " + avg);
}
}
}
I would appreciate any help. Thank you!
you can ask user for input of comma delimited numbers. Or, you can repeat input until user enters something like 0. I that case, you can change your program into this:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Averages
{
class Program
{
static void Main(string[] args)
{
//list to hold your numbers, way more flexible than array
List<double> enteredNubers = new List<double>();
//message user
Console.WriteLine("Enter number(s) or 0 to end: ");
//run this block of code indefinitely
while (true)
{
//take user input
string userinput = Console.ReadLine().Trim();
//if user enters 0, exit this loop
if (userinput == "0")
break;
double num;
//try to convert text to number
if (double.TryParse(userinput, out num))
{
//if it is successful, add number to list
enteredNubers.Add(num);
}
else //else message user with error
Console.WriteLine("Wrong input. Please enter number or 0 to end");
}
//when loop is exited (when user entered 0), call method that calculates average
Average(enteredNubers);
Console.ReadKey();
}
static void Average(List<double> numbers)
{
double sum = 0;
//go through list and add each number to sum
foreach (double num in numbers)
{
sum += num;
}
//or, you can sum it using linq like this:
//sum = numbers.Sum();
//or you can even calculate average by calling Average method on list, like numbers. Average();
//show message - all the entered numbers, separated by comma
Console.WriteLine("You have entered: " + string.Join(", ", numbers.ToArray()));
//write average
Console.WriteLine("The average is: " + sum/numbers.Count);
}
}
}
Let's solve the problem step by step. First we want to add a single double:
private static bool ReadDouble(out double value) {
value = 0.0;
while (true) {
Console.WriteLine("Enter number or X to exit:");
string input = Console.ReadLine().Trim();
if (input == "X" || input == "x")
return false;
else if (double.TryParse(input, out value))
return true;
Console.Write("Syntax error, please, try again.");
}
}
Now we are ready to read arbitrary number of values. Since we don't know the number, List<double> is a better choice than double[]
using System.Collections.Generic;
...
private static List<double> ReadDoubles() {
List<double> result = new List<double>();
while (ReadDouble(out var value))
result.Add(value);
return result;
}
Finally, we want to compute average
static void Main(string[] args) {
List<double> list = ReadDoubles();
if (list.Count <= 0)
Console.WriteLine("Empty list: no average");
else {
double sum = 0.0;
foreach (double item in list)
sum += item;
double avg = sum / list.Count;
Console.Write("The average is: " + avg);
}
}
However, you can do it in just few lines via Linq:
using System.Collections.Generic;
using System.Collections.Linq;
...
static void Main(string[] args) {
Console.WriteLine("Enter numbers separated by spaces, e.g. 1 2 3 15");
double avg = Console
.ReadLine()
.Split(new char[] { ' '}, StringSplitOptions.RemoveEmptyEntries)
.Select(item => double.Parse(item))
.Average();
Console.Write($"The average is: {avg}");
}
Here Update your methods Accordingly
static void Main(string[] args)
{
Console.WriteLine("Type Exit to stop the program... \nEnter number");
List<double> doubleList = new List<double>();
string input = Console.ReadLine();
double d;
while(!input.Equals("Exit"))
{
if(String.IsNullOrEmpty(input) || !Double.TryParse(input,out d))
{
break;
}
doubleList.Add(d);
input = Console.ReadLine();
}
average(doubleList);
Console.ReadKey();
}
static void average(List<double> doubleData)
{
double total = 0;
foreach (double number in doubleData)
{
total += number;
}
Console.WriteLine("Average = " + total/doubleData.Count);
}
Something like the following should meet your needs:
string stopLine = "STOP";
List<double> lines = new List<double>();
string line;
while ((line = Console.ReadLine()) != stopLine) {
lines.Add(Convert.ToDouble(line));
}
Average(lines);
Console.ReadLine();
Now your average method becomes
private static void Average(List<double> lines) {
Console.WriteLine(lines.Average());
}
Note that you should handle the case where the input is not a number.
static void Main(string[] args)
{
Console.WriteLine("Enter number(s): ");
string input = "";
List<double> doubleList = new List<double>();
while (input != "q")
{
input = Console.ReadLine();
if(input != "q")
{
try
{
doubleList.Add(Convert.ToInt32(input));
}
catch
{
Console.WriteLine("Invalid input");
}
}
}
average(doubleList);
Console.ReadKey();
}
static void average(List<double> myList)
{
double sum = 0;
Console.Write("You have entered: ")
foreach (int element in myList)
{
sum += element;
Console.Write(element + ", ");
}
Console.WriteLine("");
double avg = sum / myList.Count;
Console.WriteLine("The average is: " + avg);
}
static void Main(string[] args)
{
var numbers = new List<double>();
Console.WriteLine("Enter the three numbers, one per line");
for (var i = 0; i < 3; ++i)
{
while (true)
{
if (double.TryParse(Console.ReadLine(), out var enteredNumber))
{
//the number is a number, so...
numbers.Add(enteredNumber);
break;
}
//if not a number...
Console.WriteLine("That's not a number, try again");
}
}
Average(numbers);
Console.ReadKey();
}
static void Average(IEnumerable<double> numbers)
{
var average = numbers.Average();
Console.Write("You have entered: ");
foreach (var num in numbers)
{
Console.Write($" {num} ");
}
Console.WriteLine(String.Empty);
Console.WriteLine("The average is: " + average);
}
In general, Lists are better than Arrays for this kind of thing; List's are stretchy, Arrays are not. If you want this to work with 4 (or 200) numbers, all you have to do is change the for loop's bounds.
I'm using double.TryParse, this way I can let the user correct a badly entered number (always assume users will enter bad data). I'm passing the collection of numbers to the average function as an IEnumerable and not a List (the Average function is hardly needed (note that the calculation of the average is just an extension method on collections of numerics) but you had one, so I included it. An IEnumerable cannot be changed by the called function, so it's more appropriate here (and, all lists (and all arrays, for that matter) are enumerable).
Looking at all these fancy answers,i guess people are forgetting the basics of programming.
The OP literally states using arrays and instead of that you all are pushing him into hard to read code. The guy is trying to learn the basics which obviously no one cares to learn about.
Dear Cyrus don't get into generics right away. I would suggest that you stick to arrays for a while.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter number(s): ");
double[] values = new double[3]; //initialize double array with its size
for (int i = 0; i < values.Length; i++)
{
//iterate through the array and assign value to each index of it.
values[i]=Convert.ToDouble(Console.ReadLine());
}
average(values);
Console.ReadKey();
}
//set method that accepts double array as parameter
static void average(double[] values)
{
double average =0;// declare var that will hold the sum of numbers
int length = values.Length;//get array length, use it to divide the summation of numbers
Console.WriteLine("You have entered: ");
for (int i = 0; i < values.Length; i++)
{
//also display the numbers if you need to
Console.WriteLine(values[i]);
//iterate through each value in the array and sum it up.
average = values[i] + average;
}
//divide the sum of numbers by the length of array
Console.WriteLine("The average is: " + (average/length));
}
}
You can also dynamically set the length of the array by letting the user input its length, just play with code and let your imagination loose. Happy coding!
You have a couple options. Either ask for the user input to be delimited somehow. For example a comma delimited user input would be"1, 2, 3, 4". You've then got to worry about parsing that and ensuring the user entered valid input.
Another option is to have a while loop that has Console.ReadLine() within, and you only exit the loop when the user enters a pre-determined exit word (such as "stop" or exit")
static void Main(string[] args)
{
var inputValues = new List<double>();
while (true)
{
var input = Console.ReadLine();
if (input.Equals("stop", StringComparison.InvariantCultureIgnoreCase))
break;
if (double.TryParse(input, out double inputValue))
{
inputValues.Add(inputValue);
}
else
{
Console.WriteLine("Invalid input!");
}
}
PrintAverage(inputValues);
Console.ReadKey();
}
static void PrintAverage(IEnumerable<double> values)
{
Console.WriteLine("You have entered: {0}", string.Join(", ", values));
Console.WriteLine("The average is: {0}", values.Average());
}
Here I've opted for the second option. It'll continuously loop until the input is stop. It will also now try parse the value rather than directly convert, and will print a warning message if the parse failed.
If the parse was successful it's added to our inputValues collection. Once out of the while loop, we pass the collection to PrintAverage - a method that takes an IEnumerable<double> (could be one value, 100 values, or no values). Because List implements IEnumerable, we can pass our list to this method. IEnumerable has an Average() method built-in.

1. How can I get my random number to be different each time it is printed out? 2. Are there any basic things that I can improve upon? [duplicate]

This question already has answers here:
Random number generator only generating one random number
(15 answers)
Closed 4 years ago.
I am very new to programming as a whole and C# is my first language. I have been working on this project for the past few weeks or so that gives the user 3 options of whether they want to use a random number generator, calculator or roll a dice.
So far everything is going okay. I have been focusing quite a lot on exception handling and commenting to make sure that everything is as clear as possible. One problem that I have come across and am not surer how to fix is that in my dice rolling procedure it prints out the same random dice number x times rather than printing out different random numbers each time. So if you could help me fix that that would be awesome. Here is just the code for that;
static void rollDice()
{
Boolean rollAgain = false;
while (rollAgain == false)
{
Console.Write("Enter the number of sides on your dice: "); //Need to do exception handling for this
int totalSides = int.Parse(Console.ReadLine());
Console.WriteLine("How many times would you like to roll the {0} sided dice?", totalSides); //Need to do exception handling for this
int numRolls = int.Parse(Console.ReadLine());
for (int i = 0; i < numRolls; i++)
{
Random rnd = new Random();
int diceNumber = rnd.Next(1, totalSides);
Console.Write("\t" + diceNumber);
}
Console.WriteLine("\nIf you like to roll a dice with a different number of sides enter Y\nTo exit the application enter N");
string doRerun = Console.ReadLine();
if (doRerun == "Y" || doRerun == "y")
{
rollAgain = false;
}
else if (doRerun == "N" || doRerun == "n")
{
rollAgain = true;
}
}
}
Also, as I'm a newbie in general, I think some feedback from more experienced users will benefit me as a whole. Is there any mistakes I've made> Any informal rules I have broken? Please let me know I will be very thankful. Here is all of the code;
static void Main(string[] args)
{
Boolean chooseRun = false;
while (chooseRun == false)
{
Console.WriteLine("To use the calculator enter C\nTo use the random number generator enter R\nTo roll a dice enter D");
string chooseProc = Console.ReadLine();
if (chooseProc == "C" || chooseProc == "c")
{
calculator();
chooseRun = true;
}
else if (chooseProc == "R" || chooseProc == "r")
{
numGenerator();
chooseRun = true;
}
else if (chooseProc == "D" || chooseProc == "d")
{
rollDice();
chooseRun = true;
}
else
{
Console.WriteLine("Sorry that was an invalid input. Please try again");
chooseRun = false;
}
}
Console.Write("Goodbye");
Console.ReadKey();
}
/// <summary>
/// Here I have a simple calculator that can do basic functions such as subtraction and then I give them the option to use it again
/// </summary>
static void calculator()
{
int loop = 1;
while (loop == 1)
{
Console.WriteLine("You chose to use the calculator!\nPress the enter key to start"); //Greet the user and give them the option of when they want to start the calculator based upon when they choose to click the enter key
Console.ReadKey(true);
int num1 = 0; //Declaring variables
int num2 = 0;
string operation = "";
int answer;
Boolean gotnum1 = false;
while (gotnum1 == false)
{
Console.Write("Enter the first number in your equation: "); //Then I give them a message to greet them and give them the option of when to start the calculator
try
{
num1 = int.Parse(Console.ReadLine());
gotnum1 = true;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Boolean gotnum2 = false;
while (gotnum2 == false)
{
Console.Write("Enter the second number in your equation: "); //Then I give them a message to greet them and give them the option of when to start the calculator
try
{
num2 = int.Parse(Console.ReadLine());
gotnum2 = true;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
Boolean gotOpr = false;
while (gotOpr == false)
{
Console.Write("Ok now enter your operation ( x , / , +, -) ");
operation = Console.ReadLine();
switch (operation)
{
case "x":
answer = num1 * num2;
Console.WriteLine(num1 + " " + operation + " " + num2 + " = " + answer);
gotOpr = true;
break;
case "X":
answer = num1 * num2;
Console.WriteLine(num1 + " " + operation + " " + num2 + " = " + answer);
gotOpr = true;
break;
case "/":
try
{
answer = num1 / num2;
Console.WriteLine(num1 + " " + operation + " " + num2 + " = " + answer);
gotOpr = true;
}
catch (DivideByZeroException e)
{
Console.WriteLine("You cannot divide by zero");
}
break;
case "+":
answer = num1 + num2;
Console.WriteLine(num1 + " " + operation + " " + num2 + " = " + answer);
gotOpr = true;
break;
case "-":
answer = num1 - num2;
Console.WriteLine(num1 + " " + operation + " " + num2 + " = " + answer);
gotOpr = true;
break;
default:
Console.WriteLine("Sorry that is an invalid input");
gotOpr = false;
break;
}
}
Console.WriteLine("Do you want to use the calculator again? Select;\nIf you would please enter /Y/\nIf not please enter /N/");
string rerun = Console.ReadLine();
if (rerun.ToUpper() == "N")
{
loop = 0;
}
}
}
/// <summary>
/// This procedure generates a random number and gives the user the option as to whether they would like to generate another
/// </summary>
static void numGenerator()
{
Console.WriteLine("You chose to use the random number generator");
Boolean moreNum = false;
while (moreNum == false)
{
Random r = new Random();
int n = r.Next();
Console.WriteLine(n);
Console.WriteLine("If you would like another number enter Y, otherwise please enter N");
string rerun = Console.ReadLine();
if (rerun == "Y" || rerun == "y")
{
moreNum = false;
}
else if (rerun == "N" || rerun =="n")
{
moreNum = true;
}
}
}
/// <summary>
/// In this procedure a virtual dice is rolled of a user inputted number of times, this too gives the user the option to roll the dice again after rolling it x times
/// </summary>
static void rollDice()
{
Boolean rollAgain = false;
while (rollAgain == false)
{
Console.Write("Enter the number of sides on your dice: "); //Need to do exception handling for this
int totalSides = int.Parse(Console.ReadLine());
Console.WriteLine("How many times would you like to roll the {0} sided dice?", totalSides); //Need to do exception handling for this
int numRolls = int.Parse(Console.ReadLine());
for (int i = 0; i < numRolls; i++)
{
Random rnd = new Random();
int diceNumber = rnd.Next(1, totalSides);
Console.Write("\t" + diceNumber);
}
Console.WriteLine("\nIf you like to roll a dice with a different number of sides enter Y\nTo exit the application enter N");
string doRerun = Console.ReadLine();
if (doRerun == "Y" || doRerun == "y")
{
rollAgain = false;
}
else if (doRerun == "N" || doRerun == "n")
{
rollAgain = true;
}
}
}
You should create the Random object only once, typically create is in a static field (if you create it many times, it would generate the same values every time)
static Random rnd = new Random();

C# How do I error check the input ensuring only integers between 1-100 are accepted

I'm creating a program for a college assignment and the task is to create a program that basically creates random times table questions. I have done that, but need to error check the input to only accept integer inputs between 1-100. I can not find anything online only for like java or for text box using OOP.
Here is my code:
static void help()
{
Console.WriteLine("This program is to help children learn how to multiply");
Console.WriteLine("The program will create times table questions from 1-10");
Console.WriteLine("The user will be given 10 random questions to complete");
Console.WriteLine("The user will get a score out of 10 at the end");
Console.WriteLine("If the user gets the answer wrong, the correct answer will be displayed");
Console.WriteLine("");
Console.ReadLine();
Console.Clear();
}
static void Main(string[] args)
{
int Random1 = 0;
int Random2 = 0;
int Answer;
int Count = 0;
int Score = 0;
int input = 0;
String choice;
Console.WriteLine("To begin the Maths test please hit any key");
Console.WriteLine("If you need any help, just, type help");
choice = Console.ReadLine();
if (choice == "help")
{
help();
}
while (Count != 10)
{
Random numbers = new Random();
Random1 = numbers.Next(0, 11);
Count = Count + 1;
Random numbers2 = new Random();
Random2 = numbers.Next(0, 11);
Console.WriteLine(Random1 + "x" + Random2 + "=");
input = int.Parse(Console.ReadLine());
Answer = Random1 * Random2;
if (Answer == input)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Correct");
Score = Score + 1;
Console.ResetColor();
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Thats the wrong answer, the correct is " + Answer);
Console.ResetColor();
}
}
if (Score > 5)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Good job you got more than 5 answers correct! With a score of " + Score + " out of 10");
Console.ResetColor();
Console.ReadLine();
}
else if (Score < 5)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("");
Console.WriteLine("Try again you got less than 5 correct! With a score of " + Score + " out of 10");
Console.ResetColor();
Console.ReadLine();
}
}
}
}
Firstly, I suggest you to use TryParse instead of Parse to prevent unexpected errors because of invalid inputs. So, try something like that;
Random numbers = new Random();
Random1 = numbers.Next(0, 11);
Count = Count + 1;
Random numbers2 = new Random();
Random2 = numbers.Next(0, 11);
Console.WriteLine(Random1 + "x" + Random2 + "=");
//Modified
int input = 0;
while (true)
{
if (!int.TryParse(Console.ReadLine(), out input))
{
Console.WriteLine("Invalid Input. Please enter a valid integer.");
}
else
{
if (input >= 1 && input <= 100)
{
break;
}
Console.WriteLine("Invalid Input. Please enter a integer between 1-100.");
}
}
//Modified
I'd simply use a loop that will keep asking for input until it
matches your requirement:
int MinVal = 1; // No magic numbers! You may consider placing them in a config
int MaxVal = 100; // or as static readonly class members (a bit like "const").
int input = -1;
for(;;) // "empty" for-loop = infinite loop. No problem, we break on condition inside.
{
// attempt getting input from user
bool parseOK = int.TryParse(Console.ReadLine(), out input);
// Exit loop if input is valid.
if( parseOK && input >= MinVal && input <= MaxVal ) break;
Console.WriteLine( "Errormessage telling user what you expect" );
}
You may also consider granting only N trys to get the input right.
A few hints:
do not use "magic numbers". Define constants or put numbers into Properties/Settings. Name them self-explanatory and document why you chose the value they happen to have.
The errormessage should tell the user what an expected valid input is (as opposed to what they typed in) not just that their input was invalid.
Whats about this?
input = int.Parse(Console.ReadLine());
if(input > 1 && input < 100){
// valid
}else{
// invalid
}

Categories