So im trying to simply check if my variable is entered as a string, I want the if statement to go through and not an unhandled exception...
Here's my code:
Console.Write("Input: ");
int i;
bool success = int.TryParse("", out i);
if (success) {
Console.WriteLine("Enter Integer!");
} else {
i = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Output: ", i);
}
So what am I doing wrong here? Every time I am entering a string, I'm not getting to the if statement, only a crash!
The problem in your code is that the value passed to TryParse has no connection to the value passed to Convert.ToInt32. You should read the value in, then call TryParse with the same value:
Console.WriteLine("Enter an integer:");
var s = Console.ReadLine();
int i;
if (int.TryParse(s, out i)) {
Console.WriteLine("You entered an integer");
} else {
Console.WriteLine("You did not enter an integer");
}
If you would like to continue reading until the end-user enters a valid int, add a loop, like this:
int i;
do {
Console.WriteLine("Enter an integer:");
var s = Console.ReadLine();
} while (!int.TryParse(s, out i));
I think you should do it this way
Console.Write("Input: ");
int i;
bool success = int.TryParse(Console.ReadLine(), out i); //Getting the input and checking it
if (!success)
{
Console.WriteLine("Enter Integer!");
}
else
{
Console.WriteLine("Output: ", i);
}
In your code you were getting the value in the else statement and if your input cannot be parsed to int, then exception throws.
Related
I´m having problems with getting my code to work while using TryParse to catch if the user where to input a string instead of a int. If I use it as it looks now I only get the base value of 0 if something other than an int is input. I want it to show an error message to the user.
Have tried messing around with a number of different ways of using TryParse but none of them has really been helpfull.
static void Main(string[] args)
{
Random r = new Random();
int speltal = r.Next(1,21);
bool play = false;
int myNum;
while (!play)
{
Console.Write("\n\tGuess a number between 1 and 20: ");
Int32.TryParse(Console.ReadLine(), out myNum);
if (myNum < guessNum)
{
Console.WriteLine("\tThe number you have guessed is to low");
Console.ReadLine();
}
if (myNum > guessNum)
{
Console.WriteLine("\tThe number you have guessed is to high");
Console.ReadLine();
}
if (myNum == guessNum)
{
Console.WriteLine("\tCongratulations you guessed the right number!");
Console.ReadLine();
}
I want it show an error message to the user if they put in anything other than a int. It also have to include TryParse according to my teatcher
You're not capturing the bool output of TryParse so you have no idea if a non-numeric value was entered. Try something like this:
bool isValid;
do
{
Console.Write("\n\tGuess a number between 1 and 20: ");
isValid = Int32.TryParse(Console.ReadLine(), out myNum);
if(!isValid)
{
Console.WriteLine("\n\tInvalid input detected. Please try again.");
}
} while(!isValid)
The TryParse method can only put integers in the passed variable (as it is of type int), so if the value passed to it can't be parsed into an integer, the default value of int (0) will be assigned to the variable.
The way TryParse tell you if it successfully parsed the number or not, is by returning a boolean indicator.
You can try this:
while (true)
{
bool valid = int.TryParse(Console.ReadLine(), out myNum);
if(valid)
break;
Console.WriteLine("Input invalid. Please try again");
}
TryParse returns a Boolean which indicates if the input string was successfully parsed or not. Both of the answers above are correct on how to handle a invalid input but, here is a cleaner version which will also uphold the rule, between 1 and 20:
while (true)
{
Console.Write("\n\tGuess a number between 1 and 20: ");
//Checks to see if the input was successfully parsed to a integer also, performs a Trim on the input as to remove any accidental white spaces that a user might have typed in, e.g. "1000 "
if (int.TryParse(Console.ReadLine().Trim(), out myNum))
{
//Checks to see if the parsed number is in the specified range
if ((myNum > 0) && (myNum < 21))
{
break;
}
Console.WriteLine("\tThe input number was out of the specified range.");
}
else
{
Console.WriteLine("\tFailed to parse the input text.");
}
//Optional, makes the thread sleep so the user has the time to read the error message.
Thread.Sleep(1500);
//Optional, clears the console as to not create duplicates of the error message and the value of Console.Write
Console.Clear();
}
// Continue here, if (myNum < guessNum) . . .
You should use the bool returned by TryParse. Something that looks like this:
Updated answer:
static void Main(string[] args)
{
Random random = new Random();
int guessNum = random.Next(1, 21);
while(true)
{
Console.WriteLine("Guess the number between 1 and 21.");
if (Int32.TryParse(Console.ReadLine(), out int input))
{
if (input == guessNum)
{
Console.WriteLine($"You guessed it right. The number is {input}");
if(ShouldContinue())
{
guessNum = random.Next();
continue;
}
else
{
break;
}
}
if (input < guessNum)
Console.WriteLine("The number you guessed is smaller.");
else
Console.WriteLine("The number you guessed is bigger");
}
else
{
Console.WriteLine("Please enter a number between 1 and 21 as your guess");
}
}
}
static bool ShouldContinue()
{
while (true)
{
Console.WriteLine($"Do you want to continue playing? (y/n)");
string continueInput = Console.ReadLine().Trim().ToLower();
if (continueInput == "y")
return true;
else if (continueInput == "n")
return false;
else
Console.WriteLine("Invalid input!. Please choose 'y' or 'n'.");
}
}
Old answer:
while (true)
{
if (Int32.TryParse(inputInt, out int myNum))
{
// your logic goes here, too low/high or correct answer.
}
}
I've put in a loop with Try.Parse so that if the user enters a decimal number, the program will ask them to enter another number until they put in a integer and then the program will carry on with the next part.
However what i'm struggling with is putting in another loop that makes it so that the user can only enter a number between 1 and 100, and if they don't there should be an error message that loops until they do enter this. Id like them to run at the same time and i have this one, but i want it to also check whether its in the range and i'm not sure how to do that.
I'm new to programming so I'm not great at this.
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("Please Enter A Valid Integer Value");
Console.WriteLine();
inputcost = Console.ReadLine();
}
}
Your problem here is that the result variable you're looking at is only written once: outside the loop. Consider trying something like the following pseudocode (a do-while loop works exactly the same as a while loop, except it always gets executed once before the condition is checked):
bool validInput;
do
{
// If you set it true to begin with, you can set it false on any unmet conditions
// If it doesn't get set false, you've got a valid input and can exit the loop.
validInput = true;
Read input from user
Check if it's a valid integer, if not print message and validInput = false
Check if it's between 1-100, if not print message and validInput = false;
} while (!validInput);
Then if you want to tackle something more advanced, look at the continue keyword.
Try something like this.
string inputcost;
string inputmoney;
int validcost;
int validmoney;
int changereq;
while (true)
{
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
if (!(valuecost >=1 && valuecost <=100))
{
Console.Write("Please enter value between 1 and 100.");
}
bool result = int.TryParse(inputcost, out validcost);
if (result == true)
{
Console.Write("Valid Value");
}
if (result == false)
{
Console.Write("Please Enter A Valid Integer Value");
}
}
It would be useful to use a method and do something like:
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
bool result = false;
while (!result)
{
result = checkNumber();
}
public static bool checkNumber()
{
if(inputcost < 1 || inputcost > 100)
{
Console.Write("Please Enter a valid value: ");
inputcost = Console.ReadLine();
return false;
}
else
return true;
}
Hope this helps.
string inputcost;
string inputmoney;
int validcost = 0;
int validmoney = 0;
Console.Write("Please Enter The Cost, In Pennies, Of The Item You Have Purchased: ");
inputcost = Console.ReadLine();
// only accept integers
while (!int.TryParse(inputcost, out validcost))
{
Console.Write("Please Enter An Integer Value: ");
inputcost = Console.ReadLine();
}
// valid integer input in variable validcost
bool done = false;
while (!done)
{
Console.Write("Enter an integer between 1 and 100: ");
inputmoney = Console.ReadLine();
if (int.TryParse(inputmoney, out validmoney))
{
if (validmoney > 0 && validmoney < 101)
{
done = true;
}
else
{
Console.WriteLine("Invalid input: " + inputmoney);
}
}
else
{
Console.WriteLine("Invalid input: " + inputmoney);
}
}
//validcost is an integer and validmoney is an integer between 1 and 100
Console.WriteLine("validcost: " + validcost + " validmoney: " + validmoney);
Console.ReadKey();
back: Console.Write("The first number= ");
int x = int.Parse(Console.ReadLine());
if (x== string ) { goto back;} // here my proplem
How can I model this: Meaning if x input string goto back
Use a loop with int.TryParse that checks if the value is number and break from the loop when the Number is entered correctly.
int x;
while(true)
{
Console.Write("The first number= ");
bool success = int.TryParse(Console.ReadLine(), out x);
if (success)
break;
}
Or if you wish to use goto
int x;
back:
Console.Write("The first number= ");
bool success = int.TryParse(Console.ReadLine(), out x);
if (!success)
goto back;
I've read that using "goto" in C# is not recommended
However, my code uses goto and so far, errors appeared when trying to avoid "goto"
anum1r:
Console.Write ("What is the first number? ");
try {
num1 = Convert.ToDouble (Console.ReadLine ());
} catch (System.FormatException) {
Console.Beep ();
Console.WriteLine ("");
Console.WriteLine ("You have entered an invalid number!");
Console.WriteLine ("");
goto anum1r;
}
anum2r:
Console.Write ("What is the second number? ");
try {
num2 = Convert.ToDouble (Console.ReadLine ());
} catch (System.FormatException) {
Console.Beep ();
Console.WriteLine ("");
Console.WriteLine ("You have entered an invalid number!");
Console.WriteLine ("");
goto anum2r;
}
answer = num1 + num2;
How do I transform this code without using GOTO. ty
Use a while loop:
double num1;
while (true) {
Console.Write ("What is the first number? ");
try {
num1 = Convert.ToDouble (Console.ReadLine ());
break;
} catch (System.FormatException) {
Console.Beep ();
Console.WriteLine ("");
Console.WriteLine ("You have entered an invalid number!");
Console.WriteLine ("");
}
}
As you need this code twice, it is also a good idea to refactor it in a separate method like #James' answer. (Though it needs an extra parameter to modify the user prompt.)
You could use a while loop
private double? GetNumber()
{
double? result = null;
try {
result = Convert.ToDouble (Console.ReadLine ());
} catch (System.FormatException) {
Console.Beep ();
Console.WriteLine ("");
Console.WriteLine ("You have entered an invalid number!");
Console.WriteLine ("");
}
return result;
}
...
// prompt for first number
double? num1 = null;
while (!num1.HasValue)
{
Console.Write ("What is the first number? ");
num1 = GetNumber();
}
// prompt for second number
double? num2 = null;
while (!num2.HasValue)
{
Console.Write ("What is the second number? ");
num2 = GetNumber();
}
// calculate result
answer = num1.Value + num2.Value;
There are two good ways to improve your code:
Extract into a separate method the logic for repeatedly asking the user for a number until they enter a valid one. (Use a loop construct to handle looping rather than a goto.)
Use double.TryParse() to avoid having to catch a format exception.
If you put both of those together, you get code that looks something like this:
using System;
namespace Demo
{
public static class Program
{
private static void Main()
{
double first = askForNumber("What is the first number? ");
Console.WriteLine();
double second = askForNumber("What is the second number? ");
Console.WriteLine("\nYou entered {0} and {1}", first, second);
}
private static double askForNumber(string prompt)
{
while (true)
{
Console.Write(prompt);
double result;
if (double.TryParse(Console.ReadLine(), out result))
return result;
Console.Beep();
Console.WriteLine("\nYou have entered an invalid number!\n");
}
}
}
}
You can use a for-loop and a collection like a double[], also use double.TryParse:
int numbers = 10;
double[] allNumbers = new double[numbers];
for (int i = 0; i < numbers; i++)
{
Console.Write("What is the {0}. number? ", i + 1);
double num;
if (double.TryParse(Console.ReadLine().Trim(), out num))
{
allNumbers[i] = num;
}
else
{
i--; // ask the user until we have the numbers
Console.Beep();
Console.WriteLine("");
Console.WriteLine("You have entered an invalid number!");
Console.WriteLine("");
}
}
double answer = allNumbers.Sum(); // LINQ so add using System.Linq;
Another way is to extract a method for this purpose:
private static double? ReadNumberFromConsole()
{
double num;
if (double.TryParse(Console.ReadLine().Trim(), out num))
return num;
else
return null;
}
That makes the code more readable:
for (int i = 0; i < numbers; i++)
{
Console.Write("What is the {0}. number? ", i + 1);
double? num = ReadNumberFromConsole();
if (num.HasValue)
{
allNumbers[i] = num.Value;
}
else
{
i--; // ask the user until we have the numbers
Console.Beep();
Console.WriteLine("");
Console.WriteLine("You have entered an invalid number!");
Console.WriteLine("");
}
}
I would also highly recommend avoid using Convert.ToDouble on user input.
Using exceptions as an input validating system is wrong on every level.
Use something like this instead:
double GetNumberFromUser() {
double Num = double.NaN;
while(!double.tryParse(Console.ReadLine(), out Num) && !double.IsNaN(Num))
{
Console.Beep();
Console.WriteLine("");
Console.WriteLine("You have entered an invalid number!");
Console.WriteLine("");
}
return Num;
}
why test for IsNaN also? read this.
You MAY simply use a loop:
double PromptForNumber(string message) {
while (true) {
Console.Write(message + " ");
try {
return Convert.ToDouble(Console.ReadLine());
} catch (FormatException) {
Console.Beep();
Console.WriteLine();
Console.WriteLine("You have entered an invalid number!");
Console.WriteLine();
}
}
}
Used as:
double num1 = PromptForNumber("What is the first number?");
double num2 = PromptForNumber("What is the second number?");
BUT here you're also using exceptions where they're not necessary. Invalid user input is not exceptional and there are better ways to handle that:
double PromptForNumber(string message) {
while (true) {
Console.Write(message + " ");
double number;
if (Double.TryParse(Console.ReadLine(), out number))
return number;
Console.Beep();
Console.WriteLine("\nYou have entered an invalid number!\n");
}
}
Note that this way you'll also handle OverflowException that you left out in your original code.
Do you need 100 inputs? One line of code:
var inputs = Enumerable.Range(1, 100)
.Select(x => PromptForNumber(String.Format("Enter number #{0}:", x)));
private Double InputNum1
{
Console.Write ("What is the first number? ");
try
{
num1 = Convert.ToDouble (Console.ReadLine ());
return num1;
}
catch (System.FormatException)
{
Console.Beep ();
Console.WriteLine ("");
Console.WriteLine ("You have entered an invalid number!");
Console.WriteLine ("");
InputNum1();
}
}
you can use a while to query for numbers until they are valid:
double? num1 = null;
while (num1==null){
Console.Write ("What is the first number? ");
try {
num1 = Convert.ToDouble (Console.ReadLine ());
} catch (System.FormatException) {
Console.Beep ();
Console.WriteLine ("");
Console.WriteLine ("You have entered an invalid number!");
Console.WriteLine ("");
}
}
When I try to enter the quit string, xxx, why does it throw an exception? It works in a while loop, but not with do...while loop.
After I convert to integer, the string variable only lets me use numeric characters (like -999) to exit the do...while loop. But I want to make the loop control variable a word like "quit" and not numbers. How can I do that?
Here is my code.
using System;
namespace StringInputPractice
{
class StringInputPractice
{
static void Main()
{
// Declarations
string inValue;
int first;
int second;
int sum;
do
{
Console.Write("\nEnter the first number. (Type \"xxx\" to exit): ");
inValue = Console.ReadLine();
first = Convert.ToInt32(inValue); //#####
Console.Write("\nEnter the second number. (Type \"xxx\" to exit): ");
inValue = Console.ReadLine();
second = int.Parse(inValue);
sum = first + second;
Console.WriteLine("\nThe sum of {0} and {1} is {2}.", first,
second, sum);
/* Things I've tried inside do { } and that don't work */
//inValue = "";
//inValue = null;
//inValue = inValue.ToString();
//inValue = first.ToString();
//inValue = second.ToString();
}
while (inValue != "xxx"); /*If you enter a non-numeric string,
* an exception is thrown at
* ##### above.
*/
Console.ReadLine();
}
}
}
Try this: use int.TryParse instead of Convert.ToInt32
public void myfun()
{
string inValue;
int first;
int second;
int sum;
do
{
Console.Write("\nEnter the first number. (Type \"xxx\" to exit): ");
inValue = Console.ReadLine();
if (int.TryParse(inValue, out first))
{
// first = Convert.ToInt32(inValue); //#####
Console.Write("\nEnter the second number. (Type \"xxx\" to exit): ");
inValue = Console.ReadLine();
if(int.TryParse(inValue, out second))
{
// second = int.Parse(inValue);
sum = first + second;
Console.WriteLine("\nThe sum of {0} and {1} is {2}.", first,
second, sum);
}
}
/* Things I've tried inside do { } and that don't work */
//inValue = "";
//inValue = null;
//inValue = inValue.ToString();
//inValue = first.ToString();
//inValue = second.ToString();
}
while (inValue != "xxx"); /*If you enter a non-numeric string,
* an exception is thrown at
* ##### above.
*/
Console.ReadLine();
}
What program are you using to code? Most programs allow you to debug your application. This means you can freeze the program and run it line by line. On each line, you can check the values of variables, and if there is an exception - you'll be able to see it.
Your error is caused by this line: first = Convert.ToInt32(inValue);
You need to first check that you're not converting letters to numbers (because that will cause an exception). You can try Int32.TryParse(), or other alternatives.
How do you expect xxx to be converted to a number ? That's impossible!
What I would do is:
Right after getting the inValue make an if statement that check if It's xxx, like that in your while() , if true then break; the loop