Im quite new to C# and am trying to write a super simple loop
while ((var_app_choice != "Exit") || (var_app_choice != "Test"))
{
//stuff
}
I have a console application where an end user will input a value
If this value is not equal (!=) to Exit OR Test then it should loop.
What am i doing wrong here?
Thanks
If you want to come out of the loop, when the User enters Exit or Test then you need the && operator not ||
while ((var_app_choice != "Exit") && (var_app_choice != "Test"))
{
var_app_choice = Console.ReadLine();
//stuff
}
I think you want and not or...
If the value of var_app_choice is "Test", then the first condition is true and the loop will execute. Similarly, if it's "Exit", then the second condition is true. In other words, you have an infinite loop...
Friend,
Consider I am having a data list as
List dataList = new List() { "Apple", "Microsoft", "exit", "Oracle", "Android" };
int i = 0;
while (dataList[i] != "exit" || dataList[i] != "test")
{
Console.WriteLine(dataList[i]);
i++;
}
You would expect that the ouput should be only Apple and Microsoft. When it encounters "exit" in index 2 it should stop.
What really happens(consider it is verifying "exit") is the first condition fails, which means NotEqualTo Operator works fine. The problem is your OR operator. Since "exit" not equals "test", the condition passed and it further enters into the loop.
Your data must not be equal to "exit" and also not equal to "test".
Think you got the problem. For your information, While(condn){} here you can mention any condition that outputs a boolean(true or false).
Thanks and Correct me if I am wrong.
Related
I am new to C# (1 week in) and I have been scratching my head with no answers. Simply put this is part of a text based game out of much larger file. The player has the option to accept or decline an incoming call. If y/Y or n/N is entered all is well. If I purposely enter an incorrect character the while loop will print "Please respond with 'Y' or 'N' only.." 3 times. I cannot work out why. If you enter 2 letters such as GG it will print it 4 times, 3 letters, 5 times and so on. I know this is an easy fix, I just need someone to point out what I've done wrong.
//INCOMING CALL
static void IncomingCall(char rawResponse)
{
// Convert response to upper
// (note method as ToUpper cannot be called conventionally on type char)
char response = char.ToUpper(rawResponse);
while (response != 'Y' && response != 'N')
{
WriteLine("Please respond with 'Y' or 'N' only..");
rawResponse = (char)Read();
response = char.ToUpper(rawResponse);
}
}
//called in main elsewhere in the file..
WriteLine("Incoming call from Tony. Press 'Y' to accept or 'N' to decline.");
char getInput = (char)Read();
IncomingCall(getInput);
I solved it, with your help by changing method to accept string and use ReadLine()
Changed
(response != 'Y' && response != 'N')
To
(response != "Y" && response != "N")
I did not realise '' and "" produce different results. I am used to Python. Thanks for the input guys.
I suggest changing the design. Let's implement ReadBool methods which incapsulates all the logic of bool value input:
public static bool ReadBool(string title) {
// We keep asking user until valid (N or Y) value is entered
while (true) {
// If we have a title, let's show it
if (!string.IsNullOrWhiteSpace(title))
Console.WriteLine(title);
// User has to press 'Y' or 'N'; no need for enter
var key = Console.ReadKey();
if (key.KeyChar == 'Y')
return true;
if (key.KeyChar == 'N')
return false;
// Invalid value; let user know it and try again
Console.WriteLine("Please respond with 'Y' or 'N' only..");
}
}
Possible usage:
bool acceptTony = ReadBool("Incoming call from Tony. Press 'Y' to accept or 'N' to decline.");
if (acceptTony) {
Console.WriteLine("Hi Tony!");
//TODO: put relevant code here
}
else {
Console.WriteLine("Declined");
//TODO: put relevant code here
}
Swap Read() with Console.Readline()[0];.
EDIT: Or change your method signature to be a string and leverage Console.Readline() as stated in the comments prior.
string question1;
//Question 1
WriteLine("What is his favourite sport? ");
WriteLine("a) Soccer");
WriteLine("b) Basketball ");
WriteLine("c) Tennis ");
WriteLine("d) Football " );
Write("your answer is: ");
question1 = ReadLine();
if (question1 != "a" || question1 != "b" || question1 != "c")
Write("That is incorrect try again");
else
Write("that is correct");
No matter what letter I put it always gives me an incorrect try again, what am I doing wrong? Also would a while loop be better when trying to create a quiz game?
Those "or" (||) operators should almost certainly be "and" (&&) operators.
Think of what happens when you enter c, for example. Obviously, that will be c but it won't be a or b, so two of the sub-conditions will be true.
In fact, that's the case no matter which of a, b, or c that you enter (if you enter something else, all three will be true). And since an x || y || z is true if any of its sub-components is true, the expression as a whole is always true. The following table hopefully illustrates this:
Input
!= "a" (A)
!= "b" (B)
!= "c" (C)
A or B or C
a
False
True
True
True
b
True
False
True
True
c
True
True
False
True
d
True
True
True
True
other
True
True
True
True
In other words, unless question1 is some sort of "Schrodinger's variable" that can be all of a, b, and c at the same time, that if statement of yours will never be false.
However, if the subject's favourite sport is football, I'm not sure why you wouldn't just use the much simpler condition below:
if (question1 == "d") {
WriteLine("That is correct");
} else {
WriteLine("That is incorrect try again");
}
That approach (accepting the right answer) seems far easier than what your original code seems to be doing (rejecting all of the the wrong answers).
And, yes, a while loop probably would be better for a quiz scenario, something like the following would be a good start.
I've even added a rudimentary scoring system, because I get bored easily :-)
The points for a question reduce if you answer wrongly: two points for a correct answer first time, one point if you get it right second time, no points otherwise:
int score = 0; // Done once before ALL questions.
int awardPoints;
string answer;
awardPoints = 2; // Done before EACH question.
do {
// Output the question and get an answer.
WriteLine();
WriteLine("What is his favourite sport (x to exit)? ");
WriteLine(" a) Soccer");
WriteLine(" b) Basketball");
WriteLine(" c) Tennis");
WriteLine(" d) Football" );
Write("Your answer: ");
answer = ReadLine();
// Evaluate answer (d is correct here). An x answer
// will produce no output as it assumes you want to
// just exit.
if (answer == "d") {
score += awardPoints;
WriteLine("Correct, you earned {} points, now at {}",
awardPoints, score);
} else if (answer != "x") {
// Incorrect answer. Halve question points so
// user cannot simply keep trying without
// some penalty.
WriteLine("Incorrect, try again");
awardPoints = awardPoints / 2;
}
} while (answer != 'd' && answer != 'x');
// Here, either the correct answer or 'x' was
// given. If 'x', probably want to stop asking
// questions. Otherwise go on to next question.
Please, try this way.
void Main()
{
string question1 = "";
do
{
//Question 1
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("What is his favourite sport? ");
Console.WriteLine("a) Soccer");
Console.WriteLine("b) Basketball ");
Console.WriteLine("c) Tennis ");
Console.WriteLine("d) Football ");
Console.Write("your answer is: ");
question1 = Console.ReadLine();
Console.WriteLine(question1);
if (question1 == "a" || question1 == "b" || question1 == "c")
{
Console.Write("That is incorrect try again");
}
else
{
Console.Write("that is correct");
}
} while (question1 != "q");
}
When you use || operator, as soon as any condition is true, it stops processing rest of the cases and marks the statement as true.
The best way is, to test the correct answer and put rest of the cases in else block and mark them as 'incorrect'
if (question1 == 'correctOption')
{
System.Console.Write("That is correct.");
}
else
{
System.Console.Write("That is incorrect try again");
}
The runtime evaluates from left to right. In case of || it stops at the first true and returns true. If there is nothing which is true then it returns false.
In case of && it stop at the first false and returns false.
The readable code if to check for right answer and say correct and for all others display incorrect. This will also take care of user entering any other value other than "a","b,"c" as well like say "t"
can i ask you if I can have two conditions in one while loop like this?
For example:
I've tried almost everything in my own code.
int a = 0;
bool b = false;
while(a!=5 || b!=true) {
a++;
}
Console.WriteLine("A is successfuly loaded into 5.");
Console.WriteLine("Bool is still " + b);
I expect the output to be 5, but in my program i have an infinite loop.
The variable b is set to false and does not change.
So, the condition of b!=true is always true.
This condition is on the right side of the "or" ( || ) operator.
Hence, the infinite loop results.
This is an infinite loop because of your second condition.
while(a!=5 || b!=true) uses the || (OR) operators which means as long as one of the conditions is true, the whole condition is true
T || F = T ---> True OR False == True
F || T = T ---> False OR True == True
T || T = T ---> True OR True == True
F || F = F ---> False OR False == False
You assigned b = false and then check for b!=true(equivalent to b == false [which is what you assigned it]). This condition is true and because of which it infinitely enters the loop.
Both a!=5 || b!=true have to be false for it to exit the loop.
When designing a check with multiple conditions, the key is to think about how the && and || operations work. Using || will cause the loop to continue until both conditions are false. Using && will cause the loop to continue until either condition is false.
In your case, you've used || so the loop will continue until a=5 AND b=true. Since b will never be true, you've ended up with an infinite loop.
I'm not sure the exact behavior you're looking for, but there are three similar options to write your example loop, depending on how you want the two conditions to behave:
Or
while(a != 5 || b != true) {
a++;
}
The loop will continue if: a != 5 evaluates "true" or b!= true evaluates "true" or both a != 5 and b!= true evaluates "true". The first time both expressions evaluate to "false", the loop will exit.
And
while(a != 5 && b != true) {
a++;
}
The loop will continue if both a != 5 and b!= true evaluates "true". The first time one or both of these expressions evaluates to "false", the loop will exit.
XOR
while((a != 5 && b != true) || (a == 5 && b == true )) {
a++;
}
The loop will continue if both a != 5 and b!= true evaluate "true", or both evaluate "false". The first time exactly one these two expressions evaluates to "false", the loop will exit.
You have an infinite loop because b is always false, and hence, the loop continues since || means OR, and you have implemented it to continue as long as a is not 5 OR b is not true.
A quick question about C#. I have shown my code below, I cannot not work out why the loop will never close, the Do While loop should close when the user enters "A" or "B" etc, may sound like a stupid question I'm just starting C#
do
{
Console.WriteLine("What one would you like to buy? A B C or D");
a = Convert.ToChar(Console.ReadLine());
Console.WriteLine(a);
} while (a != 'A' || a != 'B' || a != 'C' || a != 'D');
You need to use "&&" instead of "||" since you want to exit when you DO NOT enter a, b, c, or d. Currently it will continue to run forever, since a is always either not 'a' or not 'b'.
Besides fixing your issue, I suggest you go for a safer and clearer approach, as your code throws an exception if the user enters more or less than one character, and also forces the user to press ENTER.
With this code the user just needs to press one key and it doesn't matter if it's uppercase or lowercase:
char a;
do
{
Console.WriteLine("Which one would you like to buy? A B C or D");
a = Char.ToUpper(Console.ReadKey().KeyChar);
Console.WriteLine();
} while (!"ABCD".Contains(a));
replace the OR condition by AND ( && ) !
Because if you type an 'A', (a == 'A'), then "a != 'B'" is true and the OR condition is TRUE...
You should use && in your condition.
You want your loop to stop when user either enters A or B in upper or lower case.In order words you want to continue only when what user entered is not A and not B(in upper or lower case)
i'm having trouble creating a loop that will request user input and if the input is not "Y" or "N" to re-prompt the user to input over and over until they give the correct input.
while (quitOrContinue != "Y"|"N")//cant use "Y"/"N" in the same line, how do I phrase this line?
Console.Write("\nWould you like to process another set of bowling scores?");
Console.WriteLine("\nPress 'Y' to process another set or 'N' to exit the program");
Console.Clear();// this needs to happen if the input to run again is "Y"
Well, for starters, you're not actually taking any input at all from the user. You can use Console.WriteLine to output whatever sort of instructions you want from the user, but you have to actually capture them somehow.
To get input, you'd have to use Console.Read(), and you'd have to use conditional blocks to check their input. You should wrap your code in a while loop that references a sentinel value:
bool userIsDone = false;
Console.Write("\nWould you like to process...");
while (!userIsDone)
{
string userInput = Console.ReadLine();
// ...
if (userInput == "Y")
{
// process another set here
Console.WriteLine("\nWould you like to process...");
}
else if (userInput == "N")
{
// exit your program
}
else
{
Console.WriteLine("That input is invalid.");
}
}
Also, about the code you have above - you should wrap the elements inside loops in { }, and the | is the bitwise OR, not logical or. Logical or (which I'm 99% you want in this situation) is ||, and logical and is &&.
Why not use a loop ?
string input = null;
while((input = Console.ReadLine()) != "Y" || input != "N")
{
Console.WriteLine("Invalid value, please try again:");
}
Here the expression (input = Console.ReadLine()) != "Y" || input != "N" will be evaluated before and each time after the loop runs. It basically reads a line from the input stream and assign it to input variable then checks if it's not Y or N it executes the loop body and evaluates the expression again and ask for input until the condition satisfies.You can use Console.Read method to read one charachter but it returns int so you need to cast it to char.