Executing code inside the while expression statement - c#

int VillainId = -1;
Console.Write("Enter VillainId: ");
while (!int.TryParse(Console.ReadLine(), out VillainId))
{
Console.WriteLine("You need to enter a valid Villain Id!");
Console.Write("Enter VillainId: ");
}
Can someone tell me how the code inside the while(**this code here**){//rest of the code} works. I understand if it was inside the {} but its in the condition and its looping until it successfully parses a number. How does that work ?

int.TryParse returns true if it successfully parses the string it's getting from Console.ReadLine(). The ! in front of it means to reverse the boolean value returned by int.TryParse, so the while executes the code in the parens, and if int.TryParse returns false, the false gets reversed to a true and the while executes again -- and again and again, until int.TryParse returns true. "The while executes" means the code in the parens executes first, and then if the result of that is true, the body of the while executes as well.
Here's another way to write the same code. It's a little less compact, but might be easier to follow:
int VillainId = -1;
bool parseOK = false;
do
{
Console.Write("Enter VillainId: ");
parseOK = int.TryParse(Console.ReadLine(), out VillainId);
if (!parseOK)
{
Console.WriteLine("You need to enter a valid Villain Id!");
}
} while (! parseOK);

int.TryParse() returns true if the conversion was successful and the ! (logical negation operator) inverts the boolean value in his right side (!true is equals to false).
The condition in while is evaluated every loop, so, every invalid input the block code in while() will be executed.
The flow is, basically:
Console.Write("Enter VillainId: ");
// asks to user input
while (!int.TryParse(Console.ReadLine(), out VillainId))
// while the conversion is not successfull
{
Console.WriteLine("You need to enter a valid Villain Id!");
Console.Write("Enter VillainId: ");
// asks for user to input valid data
}

Related

Why does this code not work when I try to convert it

This is only a small piece of the code I'm trying to make work. The original code I wrote works but I want to make sure when the user inputs a number it is in fact a number.
Console.WriteLine("Give the number of A");
A =Convert.ToDouble( Console.ReadLine());
if (char.IsNumber(Convert.ToDouble(A)) == correct)
{
Console.WriteLine(Convert.ToDouble( A * A));
}
else
{
Console.WriteLine("Incorrecrt input");
}
The Console.WriteLine(Convert.ToDouble(A*A)); I only wrote to see if that will work and it doesn't. After the user inputs only a number I must use it in another equation for a final answer. The user must input 3 numbers.
For me, you should check is the input is a number that you can convert to double before converting it.
Console.WriteLine("Give the number of A");
var a = Console.ReadLine();
double number;
if (double.TryParse(a, out number))//double.TryParse takes a parameter and tries to convert it to double. If the convertion is successfull, sets the out parameter as result and returns true. If not, returns false. And you can use with other types like int.Tryparse(param, out outParam);
{
A = number;
}
else
{
//Not a number, show a message etc...
{
If you break this down:
A =Convert.ToDouble( Console.ReadLine());
if (char.IsNumber(Convert.ToDouble(A)) == correct)
{
}
What you're basically doing is:
Double A = Convert.ToDouble(Console.ReadLine());
Double dbl = Convert.ToDouble(A);
Boolean bl = char.IsNumber(dbl);
if (bl== correct)
{
}
So there's multiple things wrong here.
Firstly, you're trying to convert the user input without any sort of guarantee of success, so if someone typed "A" instead of a number it will throw an exception.
You should use TryParse and then if it's a valid conversion proceed.
Secondly, you're checking if a Double is a char that can be converted to a number. Obviously not because it's already a Double.
Thirdly, you're checking if a Boolean is equal to some variable called correct (which you haven't provided the definition of) so it's not clear if this is a valid comparsion.
EDIT:
This is what I would do:
bool validInput = false;
do
{
Console.WriteLine("Give the number of A");
string userInput = Console.ReadLine();
if (double.TryParse(userInput, out double result))
{
validInput = true;
Console.WriteLine(result * result);
Console.ReadLine();
}
else
{
Console.WriteLine("Invalid input. Please type a number.");
}
} while (!validInput);

How to print an error message if input is not a number?

I wonder how to print an error message if user's input is not a number.
Console.WriteLine("Water amount in ml:");
int waterAmount = Convert.ToInt32(Console.ReadLine());
Most answers from other posts don't work, because waterAmount is a Int32, not a string.
Also, sorry if my English is weak, it's not my native language
I see you did not accept the other answers. Maybe you want to make the user try again after he did not input a number. You can do that with a while loop, or easier, using the goto keyword. You simply put a tag before everything is happening (in my case, waterAmountInput), and if the input was not a number, you write your error message and go to the beginning again. Here is the code:
int waterAmount;
waterAmountInput:
Console.Write("Water amount in ml: ");
try
{
waterAmount = Convert.ToInt32(Console.ReadLine());
}
catch
{
Console.WriteLine("The water amount needs to be a number!");
goto waterAmountInput;
}
You can try using C#'s TryParse() functions.
These attempt to convert values, but if they fail they return false rather than erroring.
I would suggest trying this code:
Console.WriteLine("Water amount in ml:");
string input = Console.ReadLine();
if (Int32.TryParse(input, out var value))
// Do something here. The converted int is stored in "value".
else
Console.WriteLine("Please enter a number");
You should use TryParse function:
Console.WriteLine("Water amount in ml:");
int waterAmount = 0;
if (int.TryParse(Console.ReadLine(), waterAmount)) {
} else {
Console.WriteLine("Error Message");
}
You will need to use TryParse before presuming it to be a number.
After Console.WriteLine you can capture and parse the input and if TryParse returns false, you can display an error message.
Note: if the conversion succeeds the numeric value is available in the waterAmt local variable.
Console.WriteLine("Water amount in ml:");
var input = Console.ReadLine();
if(!int.TryParse(input, out int waterAmt))
Console.WriteLine("Input is not a number");

How could I convert a string variable to a double in C#

I am trying to convert a string variable to a double.
So far I have tried Convert.ToDouble()
string userAge;
Console.WriteLine("What is your age?");
Console.ReadLine();
Convert.ToDouble(userAge);
and when I tried to do operations on userAge it shows this error:
Program.cs(23,27): error CS0019: Operator '/' cannot be applied to operands of type 'string' and 'double' [/home/ccuser/workspace/csharp-working-with-numbers-arithmetic-operators-csharp/e3-workspace.csproj]
Program.cs(29,28): error CS0029: Cannot implicitly convert type 'string' to 'double' [/home/ccuser/workspace/csharp-working-with-numbers-arithmetic-operators-csharp/e3-workspace.csproj]
Program.cs(17,24): error CS0165: Use of unassigned local variable 'userAge' [/home/ccuser/workspace/csharp-working-with-numbers-arithmetic-operators-csharp/e3-workspace.csproj]
The build failed. Fix the build errors and run again.
Any suggestions?
To begin with, you need to assign the result of those method calls (to get the user input and then convert the string to a doulbe) to some variables so you can use them later in the code:
Console.WriteLine("What is your age?");
string input = Console.ReadLine();
double age = Convert.ToDouble(input);
But now we see there is a problem - if the user enters a non-numeric input, we'll get a FormatException.
Luckily there's a better method we can use for parsing strings to doubles: double.TryParse. This method takes in a string (the input), and an out parameter that it will set to the converted value on success (or the default value of 0 on failure). And the best thing is that it returns a bool that indicates if it was successful or not, so we can use it as a condition for a loop:
Console.Write("What is your age? ");
string userAge = Console.ReadLine();
double age;
while (!double.TryParse(userAge, out age))
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid input, please try again.");
Console.ResetColor();
Console.Write("What is your age? ");
userAge = Console.ReadLine();
}
// Now 'age' is the converted value entered by the user
Now we have a solution that will loop until the user enters a valid number. But that's a fair amount of code. What if we have to get another number from them? Probably it would be better to extract this into a method that takes in a string (to use as a prompt) and which returns the strongly-typed double result:
public static double GetDoubleFromUser(string prompt)
{
bool isValid = true;
double result;
do
{
if (!isValid)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid input, please try again.");
Console.ResetColor();
}
else isValid = false;
Console.Write(prompt);
} while (!double.TryParse(Console.ReadLine(), out result));
return result;
}
Now our main code is much more simple:
double userAge = GetDoubleFromUser("What is your age? ");
double userWeight = GetDoubleFromUser("What is your weight? ");
Now, if we want to get a little fancier, we can include an optional 'validator' argument, which is a function that takes in a double and returns a bool, which we can use to further validate the result and force the user to enter a valid number.
For example, what if we want them to choose a number from 1 to 10? We don't want to have to setup a loop again for this further validation, so let's pass a Func<double, bool> to the method so it can do the validation for us!
For example:
public static double GetDoubleFromUser(string prompt, Func<double, bool> validator = null)
{
bool isValid = true;
double result;
do
{
if (!isValid)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Invalid input, please try again.");
Console.ResetColor();
}
else isValid = false;
Console.Write(prompt);
} while (!double.TryParse(Console.ReadLine(), out result) &&
(validator == null || !validator.Invoke(result)));
return result;
}
Now we can pass in whatever validation we want to do on the input to the method! This would look something like the line of code below, and the method will not return until the user enters a valid number that's greater than or equal to 1 and less than or equal to 10:
double number = GetDoubleFromUser("Choose a number from 1 to 10: ",
x => x >= 1 && x <= 10);
You aren't assigning the result of your Convert call to a variable, you're just throwing it away. Convert doesn't alter the type of the existing variable (because, apart from other considerations, you simply can't do that in a strongly-typed language), instead it produces a new variable for you to use in your maths.
The error is, I presume without seeing the relevant code, because you tried to use userAge in your calculations which, as I've just explained, is still a string.
Also, to go back a step, you've never actually assigned the result of the ReadLine operation to the userAge variable in the first place.
This:
Console.WriteLine("What is your age?");
string userAge = Console.ReadLine();
double age = Convert.ToDouble(userAge);
would make more sense. And then use age in your calculations afterwards.

is there a way to instead of making double not freeze project and instead say invalid number?

i am new in stack overflow, but i've ran into a problem.
what i want to do exactly is an advanced calculator, but can't find out a way to give an error message (then i will add a retry option) instead of making the console freeze.
Console.Write("Type A Number: ");
double num1 = Convert.ToDouble(Console.ReadLine());
//detects numbers
if (num1 != "1")
Console.WriteLine("invalid number!");
//detects numbers
Console.Write("Type An Operator: ");
string op = Console.ReadLine();
Console.Write("Type Another Number: ");
double num2 = Convert.ToDouble(Console.ReadLine());
//the operator logic system!!!
the operator logic system detects if the operator (+ - x/* / etc) is valid, but I can't find out for number. after that, I am going to make a game, but I can't find out for this one now.
Try this:
Console.Write("Type A Number: ");
if (!double.TryParse (Console.ReadLine(), out double num1))
Console.WriteLine("invalid number!");
TryParse returns false if the entered text is not a valid double. If it is valid it returns true and puts the number into num1.
This code is going to cause you issues if the user enters an unexpected value. E.g. They enter a string instead of a number. So you need to also look for and account for that.
Best is to create different methods which will check the input and only return a valid result, otherwise to prompt the user. So you have something like this;
The main method calls submethods, so is relatively simple.
You call GetValidNumber to return the number inputs for bother number 1 and number 2
GetValidOperator to return the valid operator, which itself calls IsValidOperator to check the input is valid (as there is more to check).
Double.TryParse(...) is the main check if the double number entered is valid or not. But using TryParese it will not through an exception if the user enters an non-valid number, but rather just return false. So it is a safe way of checking user input in this case.
The code might need refining and error checking improved, but it should put you on the right course.
static void Main(string[] args)
{
double number1 = GetValidNumber("Enter first number");
string op = GetValidOperator();
double number2 = GetValidNumber("Enter second number");
Console.WriteLine($"Operation is {number1} {op} {number2}");
//Add code to perform your operation
}
private static double GetValidNumber(string message)
{
Console.WriteLine(message);
string input = Console.ReadLine();
double output;
while (!Double.TryParse(input, out output) )
{
Console.WriteLine("Invalid number! Please try again");
input = Console.ReadLine();
}
return output;
}
private static string GetValidOperator()
{
Console.WriteLine("Enter an operator + - * / ");
string input = Console.ReadLine();
while (!IsValidOperator(input))
{
Console.WriteLine("Invalid Operator! Please try again");
input = Console.ReadLine();
}
return input;
}
private static bool IsValidOperator(string input)
{
bool result = false;
if (String.IsNullOrWhiteSpace(input))
return false;
if (input.Length != 1)
return false;
if (input[0] == '+' || input[0] == '-' || input[0] == '/' || input[0] == '*')
return true;
else
return result;
}
Well, you can use Double.Parse instead of Convert.ToDouble. It will throw exception on failed conversion and you will be able to handle that.

c# loop until Console.ReadLine = 'y' or 'n'

I'm fairly new to c#, and writing a simple console app as practice. I want the application to ask a question, and only progress to the next piece of code when the user input equals 'y' or 'n'. Here's what I have so far.
static void Main(string[] args)
{
string userInput;
do
{
Console.WriteLine("Type something: ");
userInput = Console.ReadLine();
} while (string.IsNullOrEmpty(userInput));
Console.WriteLine("You typed " + userInput);
Console.ReadLine();
string wantCount;
do
{
Console.WriteLine("Do you want me to count the characters present? Yes (y) or No (n): ");
wantCount = Console.ReadLine();
string wantCountLower = wantCount.ToLower();
} while ((wantCountLower != 'y') || (wantCountLower != 'n'));
}
I'm having trouble from string wantCount; onwards. What I want to do is ask the user if they want to count the characters in their string, and loop that question until either 'y' or 'n' (without quotes) is entered.
Note that I also want to cater for upper/lower case being entered, so I image I want to convert the wantCount string to lower - I know that how I currently have this will not work as I'm setting string wantCountLower inside the loop, so I cant then reference outside the loop in the while clause.
Can you help me understand how I can go about achieving this logic?
You could move the input check to inside the loop and utilise a break to exit. Note that the logic you've used will always evaluate to true so I've inverted the condition as well as changed your char comparison to a string.
string wantCount;
do
{
Console.WriteLine("Do you want me to count the characters present? Yes (y) or No (n): ");
wantCount = Console.ReadLine();
var wantCountLower = wantCount?.ToLower();
if ((wantCountLower == "y") || (wantCountLower == "n"))
break;
} while (true);
Also note the null-conditional operator (?.) before ToLower(). This will ensure that a NullReferenceException doesn't get thrown if nothing is entered.
If you want to compare a character, then their is not need for ReadLine you can use ReadKey for that, if your condition is this :while ((wantCountLower != 'y') || (wantCountLower != 'n')); your loop will be an infinite one, so you can use && instead for || here or it will be while(wantCount!= 'n') so that it will loops until you press n
char charYesOrNo;
do
{
charYesOrNo = Console.ReadKey().KeyChar;
// do your stuff here
}while(char.ToLower(charYesOrNo) != 'n');

Categories