Keeping numbers in a range - c#

I am attempting to get some data validation done but I am really struggling with that. I have been using If statements and was hoping If (pun intended) someone could help me. I am very new to the whole thing and have a massive piece that needs to be done so far I have managed but this got me stumped. I really would like a push or something in the correct direction because it feels like I am rubbing my head against a piece of sandpaper
int iNumber1;
int iNumber2;
Console.WriteLine("Please give me 2 number between -10 and +10 and ill add them together");
Console.Write("Please enter a number: ");
iNumber1 = Convert.ToInt32(Console.ReadLine());
Console.Write("Please enter a number: ");
iNumber2 = Convert.ToInt32(Console.ReadLine());
int iResult;
//here i get the adding bit done
iResult = iNumber1 + iNumber2;
//bool bUserInput = false;
//while (!bUserInput)
//{
// string sInput = Console.ReadLine();
// if (iNumber1 < -10)
// {
// Console.WriteLine("Your are out of range please stay between -10 and +10");
// }
// if (iNumber1 < 10)
// {
// Console.WriteLine("Your are out of range please stay between -10 and +10 ");
// }
// if (iNumber2 < -10)
// {
// Console.WriteLine("Your are out of range please stay between -10 and +10");
// }
// if (iNumber2 < 10)
// {
// Console.WriteLine("Your are out of range please stay between -10 and +10");
// }
//}
if (iResult <= -10 || iResult >= 11)
{
Console.WriteLine("Out of range calculation is ignored");
}
else
{
Console.WriteLine("That number is vaild and its {0}", iResult);
}

public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Please give me 2 number between -10 and +10 and ill add them together\n");
int iNumber1 = readNumber();
int iNumber2 = readNumber();
int iResult = iNumber1 + iNumber2;
Console.WriteLine("The sum of {0} + {1} is {2}", iNumber1, iNumber2, iResult);
}
//you should use functions to avoid code repetition.
//the function below reads the user input and tries to convert it into a number.
//the validation rule is applied inside the loop.
private static int readNumber()
{
bool bUserInput;
int number;
//below is a loop that runs at least once. the loop continues
//iterating while the condition evaluates to true, otherwise it ends
//and control goes to the statement immediately after it.
do
{
Console.WriteLine("Please enter a number: ");
//Int32.TryParse receives as arguments a string to parse and
//an integer as an output argument (you need the out keyword)
//it returns true if it the string could be successfully converted
//into an integer and false if it couldn't.
bUserInput = Int32.TryParse(Console.ReadLine(), out number);
if (!bUserInput)//this will be true if the user input could not be converted
{
Console.WriteLine("Input could not be converted into an integer number");
//the continue statement is used inside a loop to skip the rest of it
//and jump directly to the test condition
continue;
}
if (number < -10 || number > 10)//the validation
{
//the error message
Console.WriteLine("Your are out of range please stay between -10 and +10");
//make sure we set the flag to false because in this case,
//Int32.TryParse has set it to true, but input is still invalid
//by the validation rules.
bUserInput = false;
}
else//the number is in range, set the flag to true
{
Console.WriteLine("Good Job!\n");
//set the flag to true, so the loop can end.
bUserInput = true;
}
}while(!bUserInput);//while this evaluates to true, the loop continues.
return number;
}
}

So you need a way to validate that a number is between -10 and +10 (inclusive). That should be easy:
bool isValid(int i)
{
return (i >= -10) && (i <= 10);
}
now you need a function to see if two numbers are both valid:
bool areValid(int i1, int i2)
{
return isValid(i1) && isValid(i2);
}
Now just assume that input is not valid, and loop until it is:
bool isValid = false;
while(!isValid)
{
Console.WriteLine("Please give me 2 number between -10 and +10 and I'll add them together");
Console.Write("Please enter a number: ");
iNumber1 = Convert.ToInt32(Console.ReadLine());
Console.Write("Please enter a number: ");
iNumber2 = Convert.ToInt32(Console.ReadLine());
isValid = areValid(iNumber1, iNumber2);
if(!isValid)
{
Console.WriteLine("Out of range calculation is ignored");
}
}
Now you know you have two valid numbers and can continue with the rest of your program.

Related

How do I bring my user input to another method?

public void PlayerChooseDraw()
{
Deck deck = new Deck();
Console.WriteLine("Number of cards in the deck is: " + deck.CardCount);
Console.WriteLine("-------------");
Console.WriteLine("How many cards do you want to draw? You can draw between 1 to 26");
int playerDraw = Convert.ToInt32(Console.ReadLine());
if (playerDraw > 26) {
Console.Clear();
Console.WriteLine("ERROR: Maximum cards to draw is 26 !");
PlayerChooseDraw();
}
else if (playerDraw < 1) {
Console.Clear();
Console.WriteLine("ERROR: Minimum cards to draw is 1 !");
PlayerChooseDraw();
}
else {
Console.Clear();
DeckCreation(playerDraw);
}
}
public void DeckCreation(?)
{
Console.WriteLine(playerDraw);
}
How can I bring the integer variable playerDraw to DeckCreation method without changing it to string or something other? Thank you.
You can direcly pass the integer to be printed by the method like this:
public void PrintNumberOfCards(int count)
{
Console.WriteLine(count.ToString());
}
I renamed playerDraw to countCardsToDraw to be more clean and relevant, thus we can call the method like that:
int countCardsToDraw = Convert.ToInt32(Console.ReadLine());
...
PrintNumberOfCards(countCardsToDraw);
Also we can use int.TryParse to manage errors:
int.TryParse(Console.ReadLine(), out var countCardsToDraw);
Here the value will be 0 in case of non integer entered.
We can check the result to loop on the user input and validate the value:
bool isUserInputValid;
do
{
Console.WriteLine("How many cards do you want to draw? You can draw between 1 to 26:");
isUserInputValid = int.TryParse(Console.ReadLine(), out var countCardsToDraw)
&& countCardsToDraw >= 1
&& countCardsToDraw <= 26;
if ( !isUserInputValid )
Console.WriteLine("Wrong value, retry.");
}
while ( !isUserInputValid );

How to ignore a line/block of code if the condition is met?

Is there a way to ignore a line/block of code if the condition is met?
I'm doing a C# .NET tutorial, and the application is a number guessing game.
I added a hint option if the user enters a wrong number (else if part):
// While guess is not correct
while (guess != correctNumber)
{
//Get users input
string input = Console.ReadLine();
// Make sure it's a number
if (!int.TryParse(input, out guess))
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Please use an actual number");
// Keep going
continue;
}
// Cast to int and put in guess
guess = Int32.Parse(input);
// Check if guess is close to correct number
if(guess == correctNumber + 2 || guess == correctNumber - 2)
{
// Tell the user that he is close
PrintColorMessage(ConsoleColor.DarkCyan, "You are close!!");
}
// Match guess to correct number
else if (guess != correctNumber)
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Wrong number, please try again");
AskForAHint(correctNumber);
}
}
// Print success message
PrintColorMessage(ConsoleColor.Yellow, "You are CORRECT!");
Basically I am asking a user if he wants a hint, and if he writes Y, the hint will be displayed. However, is there an option to display this question only once since this if statement is included in a while loop?
It would be annoying if "Do you want a hint?" question keeps displaying even if the user says Y.
My AskForAHint function:
static void AskForAHint(int num)
{
// Ask user if he wants a hint
Console.WriteLine("Do you want a hint? [Y/N]");
// Take his answer
string ans = Console.ReadLine().ToUpper();
// If the user wants a hint
if (ans == "Y")
{
// First hint number
int beginning = (num - num % 10);
// Second hint number
int finish = beginning + 10;
// Give user a hint
Console.WriteLine("The correct number is somewhere betweer {0} and {1}", beginning, finish);
}
else if (ans == "N")
{
return;
}
}
Thanks
Another way to do it would be to make the number of hints configurable (allowing the caller to specify how many hints they want to let the user ask for), and then keep track of the number of hints given in the method itself.
This would require a slight change to the AskForAHint method, however, since we don't know if the user answered "Y" or "N" to the hint question. Since AskForHint has no return value, we could have it return a bool that indicates how the user responded to the question:
static bool AskForAHint(int num)
{
var answer = GetUserInput("Do you want a hint? [Y/N]: ", ConsoleColor.Yellow);
if (!answer.StartsWith("Y", StringComparison.OrdinalIgnoreCase))
{
return false;
}
var beginning = num - num % 10;
var finish = beginning + 10;
Console.WriteLine($"The correct number is somewhere between {beginning} and {finish}");
return true;
}
Now we can keep track of how many hints the user has received by incrementing a counter in our "Game" method:
// Only ask for a hint if they have any hints (and guesses) remaining
if (hintCount < maxHints && guessCount < maxGuesses)
{
// If they asked for a hint, increase the hint count
if (AskForAHint(correctNumber)) hintCount++;
// If they didn't want a hint, max out hint count so we don't ask again
else hintCount = maxHints;
}
To test out the sample code above, I used this method below, which also allows us to configure how many total guesses the user has, what the min and max values of the range should be, and if they should be given a "directional hint", like "too high!" or "too low!":
private static readonly Random Random = new Random();
private static void PlayGuessingGame(int maxHints = 1, int maxGuesses = 10,
int rangeMin = 1, int rangeMax = 100, bool giveDirectionalHint = true)
{
if (rangeMax < rangeMin) rangeMax = rangeMin;
var correctNumber = Random.Next(rangeMin, rangeMax + 1);
var guessCount = 0;
var hintCount = 0;
WriteMessage("Welcome to the guessing game!", ConsoleColor.White);
WriteMessage("-----------------------------\n", ConsoleColor.White);
WriteMessage($"I'm thinking of a number from {rangeMin} to {rangeMax}. ", ConsoleColor.Green);
WriteMessage("Let's see how many guesses it takes you to guess it!\n", ConsoleColor.Green);
do
{
WriteMessage($"(You have {maxGuesses - guessCount} guesses left)");
var input = GetUserInput("Enter the number I'm thinking of: ", ConsoleColor.White);
int guess;
if (!int.TryParse(input, out guess))
{
WriteMessage("Please enter a whole number", ConsoleColor.Red);
continue;
}
// Only increment guesses if they entered an actual number
guessCount++;
if (guess == correctNumber) break;
if (Math.Abs(guess - correctNumber) == 2)
{
WriteMessage("You are close!!", ConsoleColor.DarkCyan);
}
if (giveDirectionalHint)
{
WriteMessage("Wrong number - too " + (guess < correctNumber ? "low!" : "high!"),
ConsoleColor.Red);
}
else
{
WriteMessage("Wrong number, please try again", ConsoleColor.Red);
}
// Only ask for a hint if they have any hints (and guesses) remaining
if (hintCount < maxHints && guessCount < maxGuesses)
{
// If they asked for a hint, increase the hint count
if (AskForAHint(correctNumber)) hintCount++;
// If they didn't want a hint, max out hint count so we don't ask again
else hintCount = maxHints;
}
} while (guessCount < maxGuesses);
WriteMessage("You are CORRECT!", ConsoleColor.Yellow);
GetKeyFromUser("\nDone! Press any key to exit...");
}
This uses the helper functions:
public static void WriteMessage(string message, ConsoleColor color = ConsoleColor.Gray)
{
Console.ForegroundColor = color;
Console.WriteLine(message);
Console.ResetColor();
}
private static string GetUserInput(string prompt, ConsoleColor color = ConsoleColor.Gray)
{
Console.ForegroundColor = color;
Console.Write(prompt);
Console.ResetColor();
return Console.ReadLine();
}
Output
You can see in the output below, I was only given a single hint. However that, combined with the directional hints, made the game easy to win:
I think you can do an "if" with a counter.
Try It
Int cont = 0; //global
// While guess is not correct
while (guess != correctNumber)
{
//Get users input
string input = Console.ReadLine();
// Make sure it's a number
if (!int.TryParse(input, out guess))
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Please use an actual number");
// Keep going
continue;
}
// Cast to int and put in guess
guess = Int32.Parse(input);
// Check if guess is close to correct number
if(guess == correctNumber + 2 || guess == correctNumber - 2)
{
// Tell the user that he is close
PrintColorMessage(ConsoleColor.DarkCyan, "You are close!!");
}
// Match guess to correct number
else if (guess != correctNumber)
{
// Print error message
PrintColorMessage(ConsoleColor.Red, "Wrong number, please try again");
if(cont == 0){
AskForAHint(correctNumber);
}
}
}
// Print success message
PrintColorMessage(ConsoleColor.Yellow, "You are CORRECT!");
And in the function add
static void AskForAHint(int num)
{
// Ask user if he wants a hint
Console.WriteLine("Do you want a hint? [Y/N]");
// Take his answer
string ans = Console.ReadLine().ToUpper();
// If the user wants a hint
if (ans == "Y")
{
cont = 1;
// First hint number
int beginning = (num - num % 10);
// Second hint number
int finish = beginning + 10;
// Give user a hint
Console.WriteLine("The correct number is somewhere betweer {0} and {1}", beginning, finish);
}
else if (ans == "N")
{
return;
}
}
Use a Member Variable Boolean, its similar to how you can avoid recursive calls.
private bool alreadyHinted = false;
static void AskForAHint(int num)
{
if (alreadyHinted) return;
alreadyHinted = true;
At some point you will need to set alreadyHinted back to false;

How do I allow the user more attempts as opposed to just restarting the game after catching a format exception?

So, I'm building this little guessing game and I recently added a try/catch to stop the console from crashing if the user inputted a wrong character (besides numbers of course). Right now it works well but it restarts the entire game, I've tried to just have the catch re-run the script starting at the "for" loop, but it breaks and the random number originally generated doesn't match.
public static void StartGame()
{
Console.Clear();
Random ran = new Random();
decimal returnValue = (ran.Next(1, 100));
Console.WriteLine("Welcome to my guessing game. I'm thinking of a number between 1 and 100, can you guess it?");
Console.WriteLine("Hint: 'Way too off' means you're greater than 25 from the answer!");
try
{
for (int guessnumber = 1; guessnumber < 6; guessnumber++)
{
var Guess = Convert.ToInt32(Console.ReadLine());
//The Guess variable is simply whatever the user inputs, which is read and used by the for loop each time it is inputed.
if (Guess == returnValue)
{
Console.WriteLine("Well done!");
Console.ReadKey();
Game.NewGame();
}
else if (Guess < returnValue)
{
Console.WriteLine("Guess higher!");
}
else if (Guess > returnValue)
{
Console.WriteLine("Guess lower!");
}
if (guessnumber == 5)
{
Console.WriteLine($"The correct answer was {returnValue}");
Console.ReadKey();
Game.NewGame();
//This if statement activates when the "guessnumber" counter has reached 5, in which case it will tell the user the correct answer, and end with a return statement.
}
//result is the absolute value of
decimal result = Math.Abs(returnValue - Guess);
if (result > 25)
Console.WriteLine("Way too off!");
if (result < 5)
{
Console.WriteLine("Very close!!");
}
if (result < 2)
{
Console.WriteLine("RED HOT!!!");
}
}
}
catch (System.FormatException)
{
Console.WriteLine("Incorrect character inputted, restarting game. . .");
System.Threading.Thread.Sleep(2000);
StartGame();
}
}
public static void NewGame()
{
Console.Clear();
string input = " ";
Console.WriteLine("Game over, would you like to play again? Y/N");
input = Console.ReadLine();
input = input.ToUpper();
if (input == "Y")
{
Console.WriteLine("Ok! Re-Initializing game...");
StartGame();
}
else
{
System.Environment.Exit(0);
}
}
}
}
As another answer stated, you can just move your try/catch inside the for loop, so the loop continues.
But you really shouldn't be relying on exception handing for something that isn't exceptional, like parsing user input.
Instead, we can use the int.TryParse method to try to parse a string to an int. The nice thing about this method is that it returns true if the parse was successful, and it sets an out parameter to the parsed value.
We can also put it in it's own method that takes in a string to be used to prompt the user, which makes the code more reusable:
public static int GetIntFromUser(string prompt)
{
int result;
bool askedOnce = false;
do
{
if (askedOnce) Console.WriteLine("Invalid input, please try again.");
Console.Write(prompt);
askedOnce = true;
} while (!int.TryParse(Console.ReadLine(), out result));
return result;
}
Now our main code is greatly simplified (also notice that the Random instance should be a class field, not created on every call to StartGame, and notice that the upper bound specified in the call to ran.Next is exclusive, so if you want to include 100 as a possible answer, make the max value 101):
private static Random ran = new Random();
public static void StartGame()
{
Console.Clear();
int randomNumber = ran.Next(1, 101);
Console.WriteLine("Welcome to my guessing game");
Console.WriteLine("I'm thinking of a number between 1 and 100, can you guess it?");
for (int guessCount = 1; guessCount < 6; guessCount++)
{
var guess = GetIntFromUser($"Guess a number (try #{guessCount}): ");
if (guess == randomNumber)
{
Console.WriteLine("Well done!");
Console.ReadKey();
Game.NewGame();
}
else if (guessCount == 5)
{
Console.WriteLine("That was your last guess.");
Console.WriteLine($"The correct answer was: {randomNumber}.");
Console.ReadKey();
Game.NewGame();
}
else
{
decimal result = Math.Abs(randomNumber - guess);
if (result > 25) Console.Write("You're way off! ");
else if (result < 5) Console.Write("Very close!! ");
else if (result < 2) Console.WriteLine("You're RED HOT!!! ");
Console.WriteLine(guess < randomNumber ? "Guess higher!" : "Guess lower!");
}
}
}
Move the Try Catch handling inside for loop. What this does is, that exceptions are handled during each guess iteration.
What you had originally was exception handling for all iterations.
Also, Dont call the StartGame Function again in your catch block. You want to allow 6 (per the for loop) Guesses and not Infinite.
Ex:
for (int guessnumber = 1; guessnumber < 6; guessnumber++)
{
try
{
}
catch (System.FormatException)
{
}
}
The simple answer is as follows:
You don't control application flow with exception handling. Catching exceptions are for exceptional circumstances, a user getting input wrong isn't exceptional... it's guaranteed.
Never ever ever ever ever (+1000) use Convert.... or int.Parse to take user input... Users make mistakes all the time, use the TryParse type methods instead, they return a bool to say if the data was successfully parsed so you can then deal with it.
Eg
var success = int.TryParse(Console.ReadLine(), out var guess);
However, you can take it one step further, and add a loop (add pepper and salt to taste)
int guess = 0;
while(!int.TryParse(Console.ReadLine(), out guess))
Console.WriteLine("Omg you had one job, just enter a number");
Additional Resources
Int32.TryParse Method
Converts the string representation of a number to its 32-bit signed
integer equivalent. A return value indicates whether the operation
succeeded.

Ending a loop by sentinel and parsing an input string as an integer

I am trying to continuously ask user for a number between 300-850. When the user enters a valid number, add it to the total and ask again. If the number is invalid, display an error. Before program ends, display the average of total number by amount of times of input. End program if user enters a sentinel value. I don't know how to check if user enters a sentinel value.
using System;
class CreditScores
{
static void Main()
{
var iterations = 0;
double total = 0;
int sum = 0;
double average = 0;
int count = 0;
Console.WriteLine("Enter value between 300 to 850.");
int first = int.Parse(Console.ReadLine());
//trying to get it to stop when sentinel value reached.
while (iterations < 1000)
{
iterations++;
Console.WriteLine("Enter value between 300 to 850.");
int input = int.Parse(Console.ReadLine());
//not sure how to check if input is a number or not
if(input == integer)
{
if( input < 850 && input > 300 )
{
total +=input;
}
}
else
{
break;
}
}
total = sum + total;
Console.WriteLine("Total is {0}", total);
average = total / count;
Console.WriteLine("The average is {0}", average);
}
}
Modification/fix of Your Method
Also, I would read all the way to the end for the more robust method you could use.
First thing I would change:
while (iterations < 1000)
{
...
}
To this (which we are not done yet, read to the end):
while (input != "calculate") // or some other string
{
...
}
Then, before the while starts, make input a string.
string input = "";
while (input != "calculate") // or some other string
{
...
}
Now, we declared an input variable that is already an int later on. Let's fix that.
Console.WriteLine("Enter value between 300 to 850.");
input = Console.ReadLine();
int value = 0;
if (int.TryParse(input, out value))
{
// Clearly it's a valid integer at this point
if (value < 850 && value > 300)
{
total += value;
}
}
else
{
// Wasn't a number, might be our sentinel.
if (input == "calculate")
break;
else
{
// Throw an error or something.
}
}
Now, we need to put it together and do some cleaning.
int total = 0;
int numbersEntered = 0;
string input = "";
while (input != "calculate")
{
Console.WriteLine("Enter value between 300 to 850.");
input = Console.ReadLine();
int value = 0;
if (int.TryParse(input, out value))
{
// Clearly it's a valid integer at this point
if (value < 850 && value > 300)
{
total += value;
numbersEntered++;
}
}
else
{
// Wasn't a number, might be our sentinel.
if (input == "calculate")
break;
else
{
// Throw an error or something.
}
}
}
Console.WriteLine("Total is {0}", total);
double average = (double)total / numbersEntered;
Console.WriteLine("The average is {0}", average);
(I know, long answer. But it should help you step through the problem in the future. Also, I wrote this all by memory, I can't guarantee it will compile.)
Update: just tested it, works as expected.
A more Robust Method
Lastly, and this is really the coolest method in my opinion, use a List<int> and some extension methods.
List<int> values = new List<int>();
string input = "";
while (input != "calculate")
{
Console.WriteLine("Enter value between 300 to 850.");
input = Console.ReadLine();
int value = 0;
if (int.TryParse(input, out value))
// Clearly it's a valid integer at this point
if (value < 850 && value > 300)
values.Add(value);
else
{
// Was outside our range
}
else
// Wasn't a number, might be our sentinel.
if (input == "calculate")
break;
else
{
// Throw an error or something.
}
}
Console.WriteLine("Total is {0}", values.Sum());
Console.WriteLine("The average is {0}", values.Average());
Advantages to this method? It saves a list of the values entered, allowing you to do more with them that you cannot do with the method you currently have. It also uses the int.Sum() and int.Average() extension methods rather than your own math.
What is this int.TryParse(string, out int) sorcery?
The int.TryParse(string, out int) method (as defined by MSDN) will take an input string, and return a boolean value that indicates if it would make a valid int structure or not.
In the case that the string is a valid int, then the int parameter is filled with the integer representation of the string.
I.e.:
string myString = "100";
int value = 0;
if (int.TryParse(myString, out value))
Console.WriteLine("myString was a valid int: {0}", value);
else
Console.WriteLine("myString was not a valid int.");
This version will return true and print: myString was a valid int: 100.
Example 2:
string myString = "blah";
int value = 0;
if (int.TryParse(myString, out value))
Console.WriteLine("myString was a valid int: {0}", value);
else
Console.WriteLine("myString was not a valid int.");
This version will return false, and print myString was not a valid int.. The value variable would also be 0.
Warning:
When using int.TryParse(string input, out int value), do not rely on the value parameter as 0 to indicate failure. If the input is "0", then the value will also be 0, and the method will return true.
You want to set the condition of your while loop to something that a user can trigger as false (the sentinel).
Then put a for loop inside that if you want to do a set number of iterations, for loops are better for situations where you know how many iterations you're doing.
BUT if you want to stick to while loops only, here's a quick code snippet you could use:
while (input != 0 && iterations < 1000) //or some sentinel value you choose
{
//Your logic here, now the loop will quit if if the user enters 0
//OR you run out of iterations
}
using System;
class CreditScores
{
static void Main()
{
double total = 0;
int sum = 0;
int count = 0;
Console.WriteLine("Enter value between 300 to 850.");
int first = int.Parse(Console.ReadLine());
//trying to get it to stop when sentihel value reached.
for (iterations = 0; iterations < 1000; iterations++)
{
Console.WriteLine("Enter value between 300 to 850.");
int input;
// Check number is integer
if (int.TryParse(Console.ReadLine(), out input)
{
if(input > 300 && input < 850)
{
total +=input;
}
}
else
{
break;
}
count++;
}
total = sum + total;
Console.WriteLine("Total is {0}", total);
double average = total/count;
Console.WriteLine("The average is {0}", average);
Console.ReadLine(); // Either this or run with Ctrl-F5
}
}
The behaviour would be to add the totals until the user entered something that couldn't be parsed, and then exit.
Does this work?
string sentinalValue = "done";
string input = "";
while (iterations < 1000 && input != sentinalValue)
{
iterations++;
Console.WriteLine("Enter value between 300 to 850.");
input = Console.ReadLine();
int value;
if (int.TryParse(input, out value))
{
if( value < 850 && value > 300 )
{
total +=input;
}
}
else
{
Console.WriteLine("That is not a number!");
}
}

How could I convert this goto into a do while loop?

class Program
{
static void Main(string[] args)
{
string choice = string.Empty;
do
{
start:
int output = 0;
int number = 0;
Console.WriteLine("Please input a number for it to be counted!");
bool conversion = int.TryParse(Console.ReadLine(), out output);
if (number < 1000)
{
switch (conversion)
{
case true:
while (number <= output)
{
Console.Write(number + " ");
number += 2;
}
break;
case false:
Console.WriteLine("ERROR: INVALID INPUT!");
goto start;
}
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW OR AT 1000 TO PREVENT OVERFLOW!");
return;
}
do // Here is the beginning of the do code
{
Console.WriteLine("\n Do you want to continue - Yes or No");
choice = Console.ReadLine();
if (choice.ToUpper() != "YES" && choice.ToUpper() != "NO")
{
Console.WriteLine("ERROR INVALID INPUT: Only input Yes or No!");
}
} while (choice.ToUpper() != "YES" && choice.ToUpper() != "NO");
} while (choice.ToUpper() == "YES");
}
}
I'm using several do while loops in this statement however I'm trumped on how I would put in a loop "ERROR INVALID INPUT:" result when a user puts in anything other than the limits of the assigned integers (i.e. putting decimals or fractions) or if they put a string. I simply used goto because I'm having trouble finding out where to put the do while loop statement. If someone could simply show me how I might replace that one goto with a do while loop then I would be very greatful. (Note if you show me ways I could optimize my code better since I'm still new I probably won't understand it but your welcome to give it your best shot!)
Short answer:
The keyword continue means to go back to the beginning of the loop. Note that this will recheck the loop condition and break if it is false. Also, most people find do-while loops less readable (and they are really rarely necessary), so try using while loops instead.
There is also the keyword break which will simply exit the loop. (not just for switch-case!)
A more readable version would look something like this:
string userAnswer = "yes";
// while is usually more readable than do-while
while (userAnswer == "yes")
{
Console.WriteLine("Please input a number for it to be counted!");
int number;
// Ask for new input until the user inputs a valid number
while (!int.TryParse(Console.ReadLine(), out number))
{
Console.WriteLine("Invalid number, try again");
}
if (number < 1000)
{
// Print from 0 to number, jumping in 2's
for (int i = 0; i <= number; i += 2)
Console.WriteLine(i + " ");
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW OR AT 1000 TO PREVENT OVERFLOW!");
continue; // Jump back to the start of this loop
}
Console.WriteLine("Continue? (Yes / No)");
userAnswer = Console.ReadLine().ToLower();
// Ask for new input until the user inputs "Yes" or "No"
while (userAnswer != "yes" && userAnswer != "no")
{
Console.WriteLine("Invalid input. Continue? (Yes / No)");
userAnswer = Console.ReadLine().ToLower();
}
}
Hey I'll post some code that may help and offer some advice. Basically declare a bool named 'loopCompleted' which will continue the do while loop until you set it to true. The downside is that it will not instantly exit the loop like return/goto/etc but this is not a problem in most cases.
You may want to use if/else instead of switch(conversion), its sort of interesting to see it done that way but its a bit over the top :)
If Int.TryParse() doesnt already return false for fractional values (e.g. [15.08] returns [true] with [15] ). Then you can store Console.ReadLine() before using TryParse, then use stringName.Contains() to check for the '.' Basically, if the conversion succeeds you also check if it contained the decimal point.
Another way to check is to do float.TryParse() then check if it is a fractional value.
bool fraction = false;
if( number % 1.0f > 0)
fraction == true;
% is called modulus, it returns the remainder of A / B
If a number has a remainder when divided by 1 it must be a fractional value.
//start:
bool loopCompleted = false;
do
{
int output = 0;
int number = 0;
Console.WriteLine("Please input a number for it to be counted!");
bool conversion = int.TryParse(Console.ReadLine(), out output);
if (conversion && number < 1000)
{
while (number <= output)
{
Console.Write(number + " ");
number += 2;
}
loopCompleted = true;
}
else
{
if(conversion == false)
{
Console.WriteLine("ERROR: INVALID INPUT!");
}
else
{
Console.WriteLine("APPLICATION ERROR: NUMBER MUST BE BELOW OR AT 1000 TO PREVENT OVERFLOW!");
}
}
} while(!loopCompleted)

Categories