This question already has answers here:
While loop with multiple conditions in C++
(4 answers)
Closed 2 years ago.
I need help with this simple question.
I'm starting to learn more about while loops and I'm not sure what I'm doing wrong.
Here's a snippet of the code that I'm working on, so when I'm using or in while loop the loop executes indefinitely. But when I use AND the loop stops can somebody please explain? Shouldn't OR be used instead as per definition?
void displayMenu() {
char option;
while (option != 'Q' or 'q') { //And or OR?
cout << "P - Print numbers" << endl;
cout << "A - Add a number" << endl;
cout << "M - Display mean of the numbers" << endl;
cout << "S - Display the smallest number" << endl;
cout << "L - Display the largest number" << endl;
cout << "Q- Quit" << endl;
cout << "Choose Your Option-" << endl;
cin >> option;
if (option == 'P' or 'p')
Print();
}
}
You have phrased your condition (option != 'Q' or 'q') like you speak it.
"option not upperQ or lowerQ".
That is understood by the compiler as "option is not upperQ; or q", where "q" is a non zero thing. Nonzeros are interpreted as "true". So the whole thing always evaluates to "true", always, even for option having a values like 'Y' or '2'.
You have to rephrase much less coloqually as
"option is not 'Q' and it is not 'q' "
and you have to use the appropriate operators. Using additional () to make sure that what you mean is understood does not hurt.
That is done as
( (option != 'Q') && (option != 'q') )
Using or, or in this case and instead of the logical && is possible in certain situations, and the additional () are not required either. The main issue is however with your choice of "or" instead of "and" and using the () is a safe way as long as you are not very familiar with the operators and their order of evaluation in expressions like this one.
Why exactly you need to use && ("and") instead of or or || is a question of what happens with the two interesting letters. Lets take 'Q' it obviously is one of the two you are looking for. But it is not 'q'. So the second part of the condition with is true. With || that is sufficient and the whole thing is evaluated to "true" and the loop continues - obviously not what you want. The same is for 'q', it is not 'Q' and there for || continues.
What you actually want is "neither" and that is the same as "not this and not that". Hence you need "not and not", !a && !b or more bluntly explicit (option != 'Q') && (option != 'q').
That can be reprhased with implicit knowledge of operator precedence (look it up and try to memorize) to option != 'Q' && option != 'q'.
Related
This question already has answers here:
If statement runs through whether conditions are met or not
(4 answers)
Closed 2 years ago.
Hello I'm having a problem where when I call my function after the user enters "Y" to start the game, the cout gets read but it becomes an infinite loop. It works just fine when you enter "N" or something thats not supposed to be entered. I am using a header file called functions to well, put all the functions if that has anything to do with it. I am still in the very early learning stages of programming, and run into so many speed bumps and just not quite sure where to turn. Any help is appreciated. (P.S. I have not yet started on the gameStart() function just because of this problem. That's not whats it's going to be in the end.)
#ifndef FUNCTIONS_H;
#define FUNCTIONS_H
#include <iostream>
using namespace std;
void startScreen()
{
void gameStart();
char answer;
cout << "Welcome to __________\n\n";
cout << "This is my fisrt ever actual program I made out of my own free will lol.\n";
cout << "It is a Text-Based Adventure game. In this game you will make a character,\n";
cout << "and explore the land of Spelet, battling enemies, leveling up, getting loot,\n";
cout << "and learning skills! You do not need to capitalize anything but your character\n";
cout << "name. If a question has (something like this), those are the choices for that \n";
cout << "interaction! Thank you for trying out my terrible little game! :)\n";
cout << "I really hope y'all enjoy it!\n\n";
cout << "Would you like to play?\n";
cin >> answer;
do
{
if (answer == 'Y' || answer == 'y')
{
gameStart();
}
else if (answer == 'N' || answer == 'n')
{
cout << "Program will now close...\n";
system("pause");
exit(0);
}
else
{
cout << "Enter a Y for yes or an N for no.\n";
cout << "Would you like to play?\n";
cin >> answer;
}
}
while (answer != 'N', 'n' || 'Y', 'y');
}
void gameStart()
{
cout << "\n\"BOOM-BOOM-BOOM...\"\n\n" << endl;
}
#endif
maybe you need:
while (answer != 'N' && answer != 'n' && answer != 'Y' && answer != 'y')
The comma operator doesn't do what you think it does. It "discards the result," as my link says.
You want the && operator (AND operator) instead:
while (answer != 'N' && answer != 'n' && answer != 'Y' && answer != 'y');
one would think this is easy, but for some odd reason, my conditional statement is ignoring user input.
If I input a character 'N' or 'n' it still executes the 'Y' portion of the conditional statement, have a look:
while (i < 10) {
cout << "Would you like "<< nameOfDish[i] << "? Please enter Y or N.\n";
cin >> userResponse;
if (userResponse == 'y' || 'Y')
{
cout << "How many orders of " << nameOfDish[i] << " would you like?\n";
cin >> quantityOfDish[i];
if (quantityOfDish[i] == 0) {
cout << "I suppose you're entitled to change your mind.\n";
}
else if (quantityOfDish[i] < 0) {
cout << "Your generosity is appreciated but I must decline!\n";
quantityOfDish[i] = 0;
}
i++;
}
else if (userResponse == 'n' || 'N')
{
i++;
}
else
{
cout << "I think you mumbled NO, so I'll just go on.\n";
i++;
}
}
Is there any particular reason why despite inputting 'n' it still goes into the 'Y' if conditional block?
I have stepped through the code in the debugger, and I noticed that the userResponse variable is being read in properly. Yet, the if condition does not seem to be working properly. Thanks!
This statement (and your other if statement) is not doing what you think it does:
if (userResponse == 'n' || 'N')
Try this instead:
if (userResponse == 'n' || userResponse =='N')
You need to define each logical operation individually in a condition check. You will have to compare userResponse with n and N separately.
if (userResponse == 'y' || userResponse == 'Y')
{
cout << "How many orders of " << nameOfDish[i] << " would you like?\n";
cin >> quantityOfDish[i];
if (quantityOfDish[i] == 0) {
cout << "I suppose you're entitled to change your mind.\n";
}
else if (quantityOfDish[i] < 0) {
cout << "Your generosity is appreciated but I must decline!\n";
quantityOfDish[i] = 0;
}
i++;
}
It's been awhile since I worked in C++, but I'm fairly sure I know what's going on.
The || operator does not work on a single conditional, there must be two complete conditionals, one on each side. Try replacing your if statement with this line:
if (userResponse == 'y' || userResponse == 'Y')
Maybe you are used to SQL? You need to repeat the userResponse
if userResponse == 'n' || userResponse == 'N'
Otherwise you are actually testing
if userResponse is 'n' or the char'N' exists
The error in this code is, as others have pointed out, the if statement. However, I feel this may need some clarification. Every C++ expression returns a value. For example.
userResponse == 'y'
returns the value 1 if userResponse is 'y' and 0 if it is anything else. The operator || returns 1 if either the left or the right expression is non-zero.
Finally, the if statement checks to see whether or not the expression is zero or non-zero. So,
if (5)
cout << "X";
else
cout << "Y";
will print X and
if (0)
cout << "A";
else
cout << "B";
will print B.
Now, we can begin to understand why your code compiled successfully, but didn't do what you wanted it to.
if (userResponse == 'y' || 'Y')
In this example, the || operator will always return 1 because the expression on the right, 'Y', will always be non-zero (specifically, it will be 89, since C++ characters are just aliases for their ASCII corresponding number). And of course,
if (userResponse == 'y' || userResponse == 'Y')
work as intended. But there is a much better solution and that would be the switch statement, whose purpose is to handle situations like this. Here it is in action:
switch (userResponse) {
case 'y':
case 'Y':
//The user answered yes, handle that situation here.
break;
case 'n':
case 'N':
//The user answered no, handle that situation here.
break;
default:
// The user did not enter a valid answer,
// handle that situation here.
break;
}
A bit earlier on an IRC channel, someone asked a question about his code - essentially, his program was running on an infinite loop:
#include <iostream>
using namespace std;
int main()
{
cout << "This program adds one to your input." << endl;
char choice = 'n';
int num = 0;
while (choice != 'y' || choice != 'Y')
{
cout << "Enter number: ";
cin >> num;
num++;
cout << "Your number plus 1 is: " << num << endl;
cout << endl << "Continue/Quit? Type 'Y' to quit, any other key to continue: ";
cin >> choice;
}
cout << "By choosing 'Y', you exit the loop." << endl;
return 0;
}
Paying attention to the loop header, it seems that the loop should be working perfectly fine, but whenever it comes time for me to enter Y or y in order to exit, the loop keeps running. Considering that the while loop won't evaluate the expression to the right if the one on the left is true, this makes it especially confusing. But in any case, even if I input Y or y the loop keeps running! I'd like a somewhat in-depth explanation of why this happens, I've been trying to reason it out, look back in my textbook etc. but I can't seem to understand why... I've changed the OR into an AND, but what makes OR so bad and causes it to malfunction?
Thanks all.
Condition (choice != 'y' || choice != 'Y') is always true, so loop will run indefinetely.
If choice == 'y', then you get (false || true) == true;
if choice == 'Y', then you get (true || false) == true.
You need to use while(choice != 'y' && choice != 'Y') instead, in this case you exit loop only if you get 'y' or 'Y', otherwise you get (true && true) and continue.
The OR operator between many statements returns true if at least 1 of the statements is true, no matter if the others are false or true. In your case, choice != 'y' || choice != 'Y' will be evaluated like this:
First statement is true: Execute while loop.
First statement is false: Check if the second statement is true.
Second statement is true: Execute while loop.
Second statement is false: don't execute while loop.
Specifically, when the compiler arrives at choice != 'y', if choice == 'Y', then it will still execute, because choice != 'y' is true, in fact choice is equals to Y, so it's different from y.
If, on the other hand, choice is equals to y, then it will check if the second statement is true, but we know that choice is equals to y, so choice is different from Y, and so on...
You make a mistake,you should change "||" to "&&"
Question: Is there a more efficient method to using operator or "|| " than what I'm using?
I'm creating the HangMan Game in which players type a letter and the only way to get out of the loop is by entering the correct word in which this case if statement is the only way out.
I'm running into a problem with my compiler, maybe is that i need to work on a better and cleaner version of my code but here is what I'm currently have so far...
// w is the word chosen
if(w1=='d' && w2=='u' && w3=='c' && w4=='k' || answer == error)
{
if(w1=='d' && w2=='u' && w3=='c' && w4=='k')
{
cout << "The word is correct \n";
}
else if (answer == error)
{
cout << " You got 5 strike you lost \n";
}
}
I'm currently using Qt Project Compiler in Ubuntu to Compile my C++ Program.
I don't have this error/ suggestion with Gcc g++ on the Command Line
/home/cristian/Qt_Programs/Hangman_Game/main.cpp:123: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
You don't need the first if statement. The second if-else will accomplish the same with or without it. That should remove the compiler suggestion.
if (w1 == 'd' && w2 == 'u' && w3 == 'c' && w4 == 'k') {
cout << "The word is correct \n";
}
else if (answer == error) {
cout << " You got 5 strike you lost \n";
}
I posted a question about how to get user input such as YES or NO to control the flow of a program using if else statements, I got a answer and now i'm a step closer to making this work, however another problem has arisen, i really need to allow for multiple inputs, for example this is what im trying:
if (input == ("YES" || "yes" || "y" || "Yes" || "Y"))
{
cout << "you said yes" << endl;
}
else if (input == "NO", "no", "n", "No","N")
{
cout << "you said no" << endl;
}
else
{
cout << "ERROR!!!" << endl;
}
Kiril Kirov posted this code that could help:
if( std::string::npos != input.find( "no" ) )
but i couldn't get it to work, and roger pate suggested this:
if (prompt && cin.tie()) {
*cin.tie() << prompt << (default_yes ? " [Yn] " : " [yN] ");
however i never tried this as its complexity is far beyond my understanding. i was hoping for a solution a beginner programmer could understand or maybe im just a really slow learner
EDIT:
I made this modification but it still doesn't work any better then before, if i give the wrong case it goes to else (error) and there is no where to add more words, (such as NO N no No) :
cout << "\nYES or NO" << endl;
string input ="";
cin >> input;
if ( std::string::npos != input.find( "yes" ) )
{
cout << "you said yes" << endl;
}
else if ( std::string::npos != input.find( "no" ) )
{
cout << "you said no" << endl;
}
else
{
cout << "ERROR!!!" << endl;
}
Add the headers
#include <algorithm>
#include <cctype>
cout << "\nYES or NO" << endl;
string input ="";
cin >> input;
transform (input.begin(), input.end(), input.begin(),tolower);
if ( (std::string::npos != input.find( "yes" )) || (std::string::npos != input.find( "y" )) )
{
cout << "you said yes \n" ;
}
else if ( (std::string::npos != input.find( "no" ) ) || (std::string::npos != input.find( "n" ) ) )
{
cout << "you said no \n" ;
}
else
{
cout << "ERROR!!! \n" ;
}
In most languages the easy way is to uppercase the string before comparing it.
In standard C++ uppercasing is, unfortunately, more complex. It has to with very heavy resistance to having any new feature that doesn't work perfectly in every conceivable case. And uppercasing is a feature that by it's nature -- different in different countries, sometimes even context-sensitive -- cannot work perfectly in every conceivable case.
Adding to that, the C library's uppercase function is a bit difficult to use correctly.
Dang, I'd give you a reasonable uppercase function right here but no time. :-( Search for earlier questions on uppercasing. That should work! :-)
Cheers,
The simpler way is to convert the case beforehand. Assuming that the user restricts its input to one of the valid strings (yes/no).
Check out Boost.String, it's a collection of algorithms on the std::string class (and specifically here case conversions routines).
It'll work great for ASCII characters, but since we're talking of std::string that should be okay, you're not planning on handling japanese or arabic are you :) ?
How about you just check first two characters of the string and see if they are n N or Y y?
I haven't used C++ strings in a while, but there are several functions which look interesting. Take a look at this site. You could for example take length of a string. Then you could take characters at positions zero, one and if available two using functions I liked to. After that see if the first character is Y,y, N, n. You could go on if you want to be even more sure that user hasn't inputted nonsense (if first letter is N or n check if second in O or o and so on), but I think that this should be enough for simple decision.