I'm working on a Programming assignment and I can't figure out why this while loop is looping infinitely. There has been other input before this loop occurs, but I have cin.ignore() to clear any junk out before this loop. I'm scratching my brain, help?
//Prompt for readiness
char ready = 'x';
while (ready != 'Y' || ready != 'y') {
cout << "READY TO START YOUR TURN " << playerName << "? ";
ready = cin.get();
}
You need to change || (OR) to && (AND). Also, reset the stream after you read with cin.get(), i.e. put the following line after:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin.clear();
(you need to #include <limits>)
Otherwise, cin.get() returns a char and leaves an extra \n (newline) in the stream, that gets read once more and you basically end up with the loop executing twice for each non-yes response.
think of boolean algebra. OR gate results in true if one or both sides are true. so, if you input 'y' or 'Y', your statement will result in returning true, since of the sides would still be true.
if you change || to && (AND gate), which returns true only if both of the sides are true, then your statement makes sense. user inputs 'y' or 'Y' (he's ready, so get him out of that loop!) and one of the sides is equal to false, hence loop terminates.
while (ready != 'Y' && ready != 'y') {
or
while (ready == 'Y' || ready == 'y') {
are statements that you meant.
change the code to this -
char ready = 'x';
while (ready != 'Y' && ready != 'y') {
cout << "READY TO START YOUR TURN " << playerName << "? ";
ready = cin.get();
}
It will resolve your issue.
Related
I've just started learning the basics in C++ and currently am trying to make a program that does a few basic things. The problem I have is occurring in the pasted function below.
At this point it literally does nothing when it runs. All I'm trying to do it make it so the function runs over and over again forever, until the user enters the letter 'q'.
The function must keep running even if the user enters some random string, anything, 'q' is the only keystroke that should stop the loop.
I have tried toying around with 'cin.whatever" and haven't found success. If you have an answer please provide as much explanation as possible. Thank you!
void menu()
{
cin.clear();
cin.ignore();
char quit = 'w';
while (quit != 'q') // while loop to allow the user infinite tries
{
cout << "Which story would you like to play? Enter the number of the story (1, 2, or 3) or type q to quit: " << endl;
cin >> quit;
if (quit < '1' or quit > '3') // make sure the user picks a valid choice
{
cout << "Valid choice not selected." << endl;
}
if (quit == '1')
{
story1(); // run story 1
}
if (quit == '2')
{
story2(); // run story 2
}
if (quit == '3')
{
story3(); // run story 3
}
if (quit == 'q')
{
cout << "good bye" << endl;
break;
}
}
}
Try adding single quotes around your 1,2,3 like you did with the q. The cin is expecting a char to be entered so evaluate it as such. e.g: if (quit == '1')
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;
}
I'm stuck as to why the condition below isn't triggering when either an 'n' or a 'y' is entered at the console. When executed you can't get out the the if statement, but i know for sure that
!(cin >> again)
isn't the culprit, as that was previously the only condition in the if statement and I was able to skip/enter the if block if a character/numeral was entered, which was as expected. Here is the code:
char again;
while (1) {
cout << endl;
cout << "I see another one, care to shoot again? (y/n): ";
if (!(cin >> again) || (again != 'n') || (again != 'y')) {
// Error checking for numberals & non 'y' or 'n' characters
cout << "Please enter 'y' or 'n' only." << endl;
cin.clear();
cin.ignore(1000, '\n');
continue;
}
break;
}
I'm stumped on this so any help would be hugely appreciated!
if(...|| (again != 'n') || (again != 'y')) {
is faulty logic. What you say is
if "again" is not n or it's not y, then do the following...
now, since "again" can't be n and y at the same time, this always evaluates to true; most probably, even your compiler notices that and just jumps right into your if's content.
What you want is something like
if(!(cin>>again) || ( again != 'n' && again != 'y') {
Because that reads
if cin>>again didn't work or again is neither n nor y then,...
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 "&&"
I want the do while loop to check to see if the entered input is R OR P. I think it is checking for both and when I get to that part when I run, it pauses for a minute and then I get "CPU Limit Exceeded (core dumped). On another related note, am I in danger of breaking something?
/************************************************/
/* Name: servcode */
/* Description: Get service type */
/* Parameters: N/A */
/* Return Value: servcode */
/************************************************/
char servcode()
{
char servcode = 'a'; // Define variable for service code
char serviceyn = 'n'; // Define variable for user verify
int i = 1; // Define variable for sentinel loop
do {
cout << "\n" << "\n" << "Please enter your service code, [R]egular or [P]remium: " << "\n";
cin >> servcode;
while ((servcode != 'R', 'P') && (i < 3));
{
cout << "\n" << "Error - invalid service code, please try again.";
cout << "\n" << "Please enter your service code: ";
cin >> servcode;
i++;
if (i == 3)
{
cout << "\n" << "Too many invalid attempts, program terminating." << "\n"
<< "Have a nice day. " << "\n" << "\n";
exit (0);
} //end if
} //end while
cout << "\n" << "You entered: " << servcode << "\n"
<< "Is that correct? [y,n]";
cin >> serviceyn;
} while (serviceyn != 'y'); // end do/while loop
return servcode;
}
The correct syntax is:
while (servcode != 'R' && servcode != 'P' && i < 3)
Note the expanded comparison and the removal of the semicolon at the end:
(servcode != 'R', 'P') is valid C++ but doesn't do what you're expecting it to do;
the semicolon makes the statement into a loop with an empty body, so it continues executing forever since the loop condition never changes.
Change:
while ((servcode != 'R', 'P') && (i < 3));
to:
while ((servcode != 'R') && (servcode != 'P') && (i < 3))
Note the removal of an unwanted semicolon.
You need to do something like this:
while(something != 'a' && something != 'b')
You're using the comma operator, which discards the results of every expression except the last, so this:
while(something != 'a', 'b')
Will compare something with a, ignore the result, and use 'b' as the condition of the loop. 'b' is a non-zero value, so it's always true and the loop goes on forever (or until memory runs out, or something else stops it).
(servcode != 'R', 'P')
Should be:
(servcode != 'R') && (servcode != 'P')
Kudos to PaulR for correction. My brain is not in gear.
Let's break down this statement and see what it's doing. I've put in some extra punctuation that does not change the meaning of the statement.
while (((servcode != 'R'), ('P')) && (i < 3)) { };
The comma operator separates two different expressions and returns the value of the second one. The first part probably does what you expect, but the second part is just a literal character 'P' which is always true!
The semicolon at the end of the statement marks the body of what will be executed as the while loop. It's a do-nothing which does not change the value of servcode or i, so obviously once you enter the loop you will never leave it. This is a common mistake.