C# Exception handling, stop the loop temporarily - c#

I'm new to C# and i would really need your help with a project.
The idea is to ask the user for 10 numbers between 1-20. The numbers that the user enters are stored in an array. In the next phase a random number i generated and then the program compare all the numbers that the user previously entered with the random number. If one of numbers matches the program write something like "You win!".
My current solution is okay and working but I want a better exception handling than the current one. Here is my problem:
As you can see in my code below I rely on a loop and try/catch to ensure that the user enters a valid number, but after testing several times I discovered that if you enter a valid input, let say the first time but not the second, the unvalid input is still sent to the for-loop and to the next index.
I want to ensure that the user enters a valid number and if not the for-loop would temporarily "pause" until the next VALID number is entered.
bool start = true; //Create a loop.
{
while (start == true)
{
try
{
for (int x = 0; x < vektor.Length; x++) //To fill my array.
{
Console.WriteLine("Enter a number between 1 and 20:");
vektor[x] = int.Parse(Console.ReadLine());
start = false;
}
}
catch
{
Console.WriteLine("Error, you need to enter a number!");
}
}
}

Make a method that asks the user a question and doesn't give an answer until it's valid:
public int Ask(string question, int lower, int upper){
while(true)
{
Console.WriteLine(question);
string input = Console.ReadLine();
bool valid = int.TryParse(input, out int inputInt); //valid is true if it was a number
valid = valid && inputInt >= lower && inputInt <= upper; //but also test was it in range?
if(valid)
return inputInt; //if not valid, repeat the question because the loop is infinite
}
}
valid will be true if the user enters a number, but if they entered 40 for a 1 to 20 range, then the second validity assessment is:
valid = true /*it was a number*/ && true /*40 is >= 1*/ && false /*40 is not <= 20*/
So valid becomes false. We can only escape the Ask() method, returning the valid number if valid is true, otherwise the loop goes round again
--
Now you can have a list of numbers, say you want 10, we can loop and add numbers to a list until we get 10:
List<int> numbers = new List<int>();
while(numbers.Count < 10)
{
int validNumber = Ask("Enter a nubmer between 1 and 20: ", 1, 20);
numbers.Add(validNumber);
}
You can do this as an array if you like:
int[] numbers = new int[10];
for(int x = 0; x<numbers.length; x++)
{
int validNumber = Ask("Enter a nubmer between 1 and 20: ", 1, 20);
numbers[x] = validNumber;
}
Because you know that the Ask method will never return unless the input is valid, so the loop "pauses"

Related

I need the loop to stop once 5 unique integers are entered into the list. The program runs but it does not stop when the unique numbers are entered

public void UniqueNumbers()
{
List<int> valueList = new List<int>();
int ListInput;
var distinctCount = 0;
while (distinctCount != 5)
{
Console.WriteLine("Please enter an integer value: ");
string? val = Console.ReadLine();
ListInput = Convert.ToInt32(val);
if (ListInput < 0 || ListInput > 100)
{
valueList.Add(ListInput);
}
distinctCount = valueList.Distinct().Count();
}
}
The integers would be placed in the list. Once the 5 unique numbers have been entered by the user, the loop should end. The if statement is to not allow numbers less than 0 or numbers greater than 100. The user will enter as many numbers as they need until 5 unique numbers are entered.
I need the loop to stop once 5 unique integers are entered into the list. The program runs but it does not stop when the unique numbers are entered
Your code works. It breaks out of the loop after 5 unique numbers are in the list.
The if statement is to not allow numbers less than 0 or numbers greater than 100.
Here's your problem. You are not checking if the number is within 0 to 100. You are checking if it is outside that range. Any number between 0 and 100 is not being added to the list. You want to flip the check like this:
if (ListInput >= 0 && ListInput <= 100)
{
valueList.Add(ListInput);
}
You can easily verify this (and debug similar problems in the future) by running your code with a debugger attached and stepping through the code line-by-line.

Error by parsing Console.Readline() to int –

I have a bit code of console application whose job is to get numbers from the user and add them to the array. But the problem is that I don't know how many numbers the user is going to input. So I decided to add some sort of stop key. For example, if there are enough numbers user can press "N" and continue to another part of code. So my first problem is how to make this code to not give unhandled format exception when any key is pressed.
int[] arrayInt = new int[100];
for (int i = 0; i < arrayInt.Length; i++)
{
arrayInt[i] = int.Parse(Console.ReadLine());
if (arrayInt[i] == Convert.ToChar (ConsoleKey.N))
{
//for example
Console.WriteLine("You pressed n");
}
If you want only a number or a letter, then you should use Console.ReadKey instead of Console.ReadLine.
You can use the following code, to get what you want.
int[] arrayInt = new int[100];
for (int i = 0; i < arrayInt.Length; i++)
{
var input = Console.ReadLine();
if(input.Equals("n")){
//for example
Console.WriteLine("You pressed n");
}else{
if(int.TryParse(input, out arrayInt[i])){
Console.WriteLine("It's a number");
}else{
Console.WriteLine("No number and no n!");
}
}
}
You uses ConsoleKey.N, to check the "n". But with this, the user have to input "N". "n" doesn't work. If you want it not case sensetive, than you can change this line from my code:
if(input.Equals("n")){
to
if(input.ToLower().Equals("n")){

c# cant run two functions in a loop?

What i want to do is to make it that inside a loop, the computer checks whether the number entered is firstly not a decimal, and at the same time i want to make sure that the number is within the range 1 - 100. My code now works in regards to having the first function about the number not being a decimal, so when i enter a decimal, an error message is displayed that tells the user to keep adding another number until an integer is added, and it then runs to the next part. However it doesn't seem to work when i put in a number outside of the range, the error message doesn't pop up and the conditions just don't seem to work. What i want to know is how do i get these two parts, the decimal and the range checking to work simultaneously. I'm really new to coding so could any explanations be simple so that i could understand. Thank you in advance!
string inputcost;
string inputmoney;
int validcost;
int validmoney;
int changereq;
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
bool result = int.TryParse(inputcost, out validcost);
while (!int.TryParse(inputcost, out validcost))
{
if (result == true )
{
Console.Write("Valid Value");
}
if (result == false)
{
Console.Write("You Cannot Enter Decimals. Please Enter A Valid Integer Value.");
Console.WriteLine();
inputcost = Console.ReadLine();
}
if (validcost < 100 && validcost > 1)
{
Console.Write("valid value");
}
else
{
Console.Write("invalid value.please enter a number between 1 and 100 ");
Console.ReadLine();
}
}
The line
while (!int.TryParse(inputcost, out validcost))
means that you enter the while loop only when the user types something that cannot be converted to an integer. If it is a valid integer the code inside the while loop is never reached and thus, your test on the valid range is never executed
Instead put everything inside the an infinite loop and provide a way to break the program (type x to quit)
while (true)
{
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: (type x to quit)");
inputcost = Console.ReadLine();
// Check if the user wants to stop executing the program
if(inputcost == "x")
break;
// Check if it is a valid integer
bool result = int.TryParse(inputcost, out validcost);
if (!result)
{
Console.WriteLine("You Cannot Enter Decimals (or strings). Please Enter A Valid Integer Value.");
}
else if (validcost > 100 || validcost < 1)
{
Console.WriteLine("invalid value.please enter a number between 1 and 100 ");
}
else
{
Console.WriteLine("Valid value");
// other code block that works with the input number....
}
}
Alternativly use another condition for your loop, something that first checks for an integer and afterwards if it is in range:
while (!int.TryParse(inputcost, out validcost)) || validCost < 1 || validCost > 100)
{
Console.WriteLine("Please enter an integer between 1 and 100");
inputCost = Console.ReadLine();
}
All the code that should be executed when your inout is valid should now gow beyond the loop, not inside it.

Comparing in Array

There is something wrong with my code. I am teaching myself c# and one of the challenges in this chapter was to prompt the user for 10 numbers, store them in an array, than ask for 1 additional number. Then the program would say whether the additional number matched one of the numbers in the array. Now what I have below does work, but only if I enter in a comparison number that is less than 10 which is the size of the array.
I'm not sure how to fix it. I am not sure how to do the comparison. I tried a FOR loop first which kind of worked, but ran through the loop and displayed the comparison against all 10 numbers so you would get 9 lines of No! and 1 line of Yes!. I put in a break; which stopped it counting all 10 but if I entered the number 5 for comparison, then I would get 4 lines of No! and 1 of Yes!. The below has been the only way I could get it to work reliably but only as long as the number isn't out of the bounds of the array.
I can see why I get the error when the number is above 10, I just don't know what to use to compare it but still allow the user to enter in any valid integer. Any assistance would be great!
int[] myNum = new int[10];
Console.WriteLine("Starting program ...");
Console.WriteLine("Please enter 10 numbers.");
for (int i = 0; i <= 9; ++i)
{
Console.Write("Number {0}: ", i + 1);
myNum[i] = Int32.Parse(Console.ReadLine());
}
Console.WriteLine("Thank you. You entered the numbers ");
foreach (int i in myNum)
{
Console.Write("{0} ", i);
}
Console.WriteLine("");
Console.Write("Please enter 1 additional number: ");
int myChoice = Int32.Parse(Console.ReadLine());
Console.WriteLine("Thank you. You entered the number {0}.", myChoice);
int compareArray = myNum[myChoice - 1];
if (compareArray == myChoice)
{
Console.WriteLine("Yes! The number {0} is equal to one of the numbers you previously entered.", myChoice);
}
else
{
Console.WriteLine("No! The number {0} is not equal to any of the entered numbers.", myChoice);
}
Console.WriteLine("End program ...");
Console.ReadLine();
You were on the right track- you want to loop through the array in myNum and compare each element to the variable myChoice. If you don't want to print whether each element of the array is a match, create a new variable and use it to keep track of whether you've found a match or not. Then after the loop you can check that variable and print your finding. You'd usually use a bool variable for that- set it false to start, then true when you find a match.
bool foundMatch = false;
for (int i = 0; i < 10; i++) {
if (myNum[i] == myChoice) {
foundMatch = true;
}
}
if (foundMatch) {
Console.WriteLine("Yes! The number {0} is equal to one of the numbers you previously entered.", myChoice);
}
If you include the System.Linq namespace (or if you change the type of myNum to be something that implements ICollection<T>, like List<T>), you can use myNum.Contains(myChoice) to see if the value myChoice matches one of the values in myNum. array.Contains returns a boolean that is true if the specified value is found in the array and false if it is not.
You can update your code to use this like so:
//int compareArray = myNum[myChoice - 1]; // This line is no longer needed
if (myNum.Contains(myChoice))
{
Console.WriteLine("Yes! The number {0} is equal to one of the numbers you previously entered.", myChoice);
}
else
{
Console.WriteLine("No! The number {0} is not equal to any of the entered numbers.", myChoice);
}
If you're looking for numbers that are definitely between 1 and 10, then before you use
int compareArray = myNum[myChoice - 1];
check if it's over the value of 10. For example:
while(myChoice > 10)
{
Console.Write("Please choose a number less than or equal to 10: ");
myChoice = Int32.Parse(Console.ReadLine());
}
The benefit of putting it inside a while loop instead of an if tag means that, when the user enters another number, the value of myChoice will be rewritten, and compared against. If they enter a number over 10, it'll keep responding Please choose a number less than or equal to 10. until the number they input is below or equal to 10:` Then, your program will continue.
However, if you want to compare it against the array, rather than put in a fixed number comparison, consider the following while loop:
while(myChoice > myNum.Length)
{
Console.Write("Please choose a number less than or equal to {0}: ", myNum.Length);
myChoice = Int32.Parse(Console.ReadLine());
}
This will work for any sized array then, without you having to change the while loops content. By using this system, you can then ensure that you won't get an IndexOutOfBounds exception, so long as you subtract 1 when using it as an index.
You are looking to compare a final, 11th value and trying to determine if its in an array of 10 previous entries?
Try:
for(int i = 0; i < array.length - 1; i++;)
{
If(array[i] == input)
return true;
}
return false;
You should be able to figure out how to implement this completely yourself, as you did want to do it as an exercise.
Edit: If someone wants to check this or complete it in correct syntax, go ahead. I posted this rough outline from a phone.

Get the sum of an array in C# but receiving int32 error

In general, I know that int32 errors mean that a string value is not getting converted for the console program. I have seen a lot of code trying to find the answer to this including the following stackoverflow questions (seen much more but these were most useful:
How to sum up an array of integers in C#
Error CS1501: I'm not overloading a Sum() method correctly
CS0019 Operator cannot be applied to operands of type 'bool' and 'int'
That being said, this is also a homework assignment, titled UsingSum.cs as seen in a couple of these links. The difference in mine and these is that I am trying to make it so that the user enters however many Integers they want, then they are added up. The entire assignment is written in link 2....
The problem: I keep getting either 0 or System.Int32[] instead of the sum, despite the changes I make.
I cannot use Linq.
Here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace UsingSum
{
class Program
{
static void Main(string[] args)
{
int i;
int usrInput;
bool running = true;
//Enter Question Asking Loop w/ running=true
while (running)
{
Console.Write("Enter a number or enter 999 to exit: ");
int[] array1 = new int[0];
for (i = 0; i < array1.Length; i++)
{
usrInput = Convert.ToInt32(Console.ReadLine());
array1[i] = Convert.ToInt32(usrInput);
}
for (i = 0; i < array1.Length; i++)
{
Console.WriteLine(array1[i]);
}
/*If the user enters 999, calls Sum() and asks user to press any key to exit.
changes 'running' from true to false to exit the question loop*/
int exit = Convert.ToInt32 (Console.ReadLine());
if (exit == 999)
{
running = false;
Sum(array1);
}
}
//Loop complete
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
public static void Sum(int[] numbers)
{
int [] sum1 = new int [0];
int sum2 = 0;
//Program accepts user responses with or w/o this loop...Int.32 error present both ways
//for (int a = 0; a < numbers.Length; ++a)
//sum1[a] = a;
//additional loop tried w/o the loop above/below;
//when used in the WriteLine w/ sum2 it displays 0, when used with sum1 or numbers Int.32 error
//Array.ForEach(sum1, delegate(int i) { sum2 += i; });
foreach (int i in numbers)
sum2 =+ i;
Console.WriteLine("The sum of the values in your array is: " + sum1);
/*tried changing 'numbers' to sum1, sum2, sum1.Convert.ToString(),sum2.Convert.ToString()
numbers.Convert.ToString(), also tried converting sum2 to a string.*/
}
}
}
Here is my final solution!
static void Main(string[] args)
{
AskUserForNumbers();
Console.WriteLine("Press any key to exit");
Console.ReadLine();
}
public static List<Int32> AskUserForNumbers()
{
bool running = true;
List<int> numbers = new List<int>();
while (running)
{
Console.Write("Enter a number or enter 999 to exit: ");
int inputValue;
var inputString = Console.ReadLine();
//Check for "999" which indicates we should display the numbers entered, the total and then exit our loop.
if (inputString == "999")
{
Console.WriteLine("The sum of the values in your array is: " + numbers.Sum());
running = false;
}
else if (Int32.TryParse(inputString, out inputValue) && inputValue > 0)
{
numbers.Add(inputValue);
}
else
{
Console.WriteLine("Please enter a whole number greater than 0");
}
}
return numbers;
}
}
}
A few problems:
First, you're always declaring your arrays as int[] array1 = new int[0];. This means that your code for actually getting the user input will never hit. Maybe you should try using a different collection type (List<int> maybe).
Second, you never perform any error checking when parsing the integer. That's bad practice. You should be using int.TryParse(string input, out result) to verify it was a valid number before adding it to the array.
Third, you are looping over the length of the array for inputs, meaning you will loop through however long the array is, and will continue doing so until the last input you have is the exit number (999).
Fourth, the input you get for the exit code is discarded (not added to the array to sum).
Just remember that programming is very procedural. There should be clear (logical) steps from point a to point b. In fact, imagine you are the program and you're asking a friend to give you numbers to sum up for him. Give him whatever information you think might be useful (such as the exit condition). Diagram the steps, and then try to translate that to code.
Edit: The main point is that an array (which has a fixed size) is NOT the tool for the job here. You're not actually filling the array with any data, so that's why the sum never happens. The culprit is here:
int[] array1 = new int[0]; // Instantiate a zero-length array? Can't hold any values
// Will never hit inside the loop here, because i < array1.Length (which is zero) will always be false.
for (i = 0; i < array1.Length; i++)
You need to either increase the size of the array to begin with (and either reuse the indexes or resize the array) or use an non-fixed collection (List, for example). Finally, when you pass array1 to the Sum method, array1 is empty because you declared it as a zero element array. That is why you always get a zero printing out. Like I said before, imagine you are the program, and actually run through all these steps, LINE BY LINE.
For example, you start in the loop. You prepare a miniature notebook to write down all the numbers your friend is telling you with no pages in it. For every page (and realize there are none) in the notebook, you ask your friend for a number. After you've gone through every page, you now go through every page again to read all the values he gave you (keep in mind he couldn't give you any numbers, since the notebook was empty). Then you ask him one more time for a number, and if it's 999 you tell him you're done and give him the sum of all the numbers you wrote down. If he didn't give you 999 as the number, you repeat the cycle.
Do you understand WHY it's not working now?
public static void Sum(int[] numbers)
{
int sum2 = 0;
foreach (int i in numbers)
sum2 =+ i;
Console.WriteLine("The sum of the values in your array is: " + sum2);
}
foreach (int i in numbers)
sum2 =+ i;
should become
foreach (int i in numbers)
sum2 += i;
Your problem is with your first for loop. You never will add items to your array because your
for (i = 0; i < array1.Length; i++)
Since you only add to your array1 array when you enter the loop, it won't ever increment. Since i = 0 and the array1.Length is 0 to start, i will never be less than the length.
Here is what I would suggest you do.
private static void Main(string[] args) {
var running = true;
var numbers = new List<int>();
//Enter Question Asking Loop w/ running=true
while (running) {
Console.Write("Enter a number or enter 999 to exit: ");
int inputValue;
var inputString = Console.ReadLine();
//Check for "999" which indicates we should display the numbers entered, the total and then exit our loop.
if (inputString == "999") {
//Display the numbers entered
foreach (var number in numbers) {
Console.WriteLine(number);
}
Console.WriteLine("The sum of the values in your array is: " + numbers.Sum());
running = false;
}
else if (Int32.TryParse(inputString, out inputValue) && inputValue > 0) {
//We have valid input, append it to our collection
numbers.Add(inputValue);
}
else {
//The user entered invalid data. Let them know.
Console.WriteLine("Please enter a whole number greater than 0");
}
}
//Loop complete
Console.WriteLine("Press any key to exit.");
Console.ReadLine();
}
You have several small mistakes here.
In your Sum method you are no longer using the array sum1, you're summing the values into sum2, but you're printing sum1. Your sum method should be (as described by Wiktor):
public static void Sum(int[] numbers)
{
int sum2 = 0;
foreach (int i in numbers)
sum2 += i;
Console.WriteLine("The sum of the values in your array is: " + sum2);
}
Also note that you used sum2 =+ i rather than sum2 =+ i. What that's saying is "set sum2 to be equal to the positive value of i" rather than, "add i to sum2.
Next, you have some issues in how you gather your input from the user. First off, arrays don't have a mutable size. The size that they have is fixed when they are created, and the array that you create to hold onto the values to sum up from the users is initialized to a size of 0. (int[] array1 = new int[0];) If you want to get a fixed number of values from the user you can put something other than 0 there for the array size, but based on the context it appears that you want the users to be able to add values until they enter 999 at which point you end. Since you don't know the size before hand you'll want to use a List<int> rather than an array, as you can just add items to it and it will magically grow to support the new items.
I would also suggest making a new method to get all of the values from the user, rather than embedding it in your Main method.
public static List<int> AskUserForNumbers()
{
List<int> numbers = new List<int>();
while(...)//todo determine end condition
{
string userInput = Console.ReadLine();
if(...)//todo determine if user is done
{
}
else
{
int nextNumber = ...;//todo parse user input
numbers.Add(nextNumber);
}
}
return numbers;
}
I'm not sure if it's a requirement for you to stop asking for numbers when the user enters 999 or if that's just what you did. if you have a choice, I would suggest using something different such as a blank line, 0, "quit", "exit", etc. 999 is a number that someone might want to sum.
As mentioned by SPFiredrake, it's best to use int.TryParse() to parse user input, that way if they enter a number that's not an int it won't crash, and you can tell the user that it was no good and they need to try again.

Categories