I'm trying to have the user be able to control when they want to exit the while loop, and also i was wondering on how to exit the program when done
cout<<"Play again? (Y/N)"<<endl;
char userInput;
cin>>userInput;
if (userInput='y'|'Y')
{
cin.clear();
cin.ignore();
input();
userInput=0;
}
else
{
exit(0);
}
return 0;
The expression userInput='y'|'Y' suffers from three fundamental problems and a compounding problem.
'y'|'Y' is not a logical OR operation. It is a bitwise OR operation.
It does not compare the value of userInput against 'y' or 'Y'.
It assigns the value of the subexpression 'y'|'Y', which evaluates to the integral value 121 in a system that uses ASCII encoding, to userInput.
As a consequence, the conditional of the if statement always evaluates to true.
What you need is:
if ( userInput == 'y' || userInput == 'Y' )
Related
I'm making a program that uses a while loop in C++. Here is my code so far:
int userInput = 0;
while (userInput != 'Z')
{
cout << "Please enter the homework score: ";
cin >> userInput;
homeworkScores.push_back(userInput);
if (userInput == 'Z') {
userInput = 'Z';
}
}
The problem im having is whenever I type Z, the loop keeps printing "Please enter the homework score: " over and over without stopping. I've defined homeworkScores as a vector earlier in the code. How can I make it stop the loop once userInput == 'Z'? Thanks in advance!
The problem you are facing, is that cin is trying to read an integer, but you provide a character in the input. cin will only ask for another input, once the input is empty, you can try this by supplying more than one integer to your code:
Please enter the homework score: 2 27 12 8
will input all four numbers and print "Please enter the homework score: " 4 additional times.
If you provide it with a character, it will not remove it from the input, so whenever "cin" is reached, it will see "Z" in the input, and continue.
You can use answers like provided here How to catch invalid input in c++? for your input sanitation, but it will not make "Z" work as a stop.
The easiest way is to chose an invalid score like -1 instead of Z, end on any invalid input or try to read a string on failure to read an int.
A simple way to exit a loop is by using the break statement.
if (userInput == 'Z') {
userInput = 'Z';
break;
}
Other ways would be to set your exit condition to resolve as false, which I think is causing some issues for you.
EDIT: As #Ganea Dan Andrei noted, reading a char from cin into an integer will cause the cin::fail() to return true. This can be reset by calling cin.clear(), which will allow you to make further inputs.
userInput is an integer, and so 'Z' would have to equal the ASCII equivalent of its char value, which is 90. The way you're doing it should shouldn't work. Instead, try making userInput a char, and then convert it to an integer so you can push it back into your vector. This might look like:
char userInput = '';
while (userInput != 'Z')
{
cout << "Please enter the homework score: ";
cin >> userInput;
homeworkScores.push_back(userInput - '0'); //Are you sure you want to push a 'Z'?
if (userInput == 'Z') {
userInput = 'Z';
break;
}
userInput = ''; // Reset your input so it doesn't keep getting pushed new values
}
What happens here is userInput - '0' is subtracting the ASCII values of your chars, and leaving you with their integer value. There are other ways to do this, but this is a commonly used way.
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'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.
I wrote a bool function again() to prompt the user to re-run the program, but for whatever answer the user enters the program will re-run no matter what.
bool again()
{
//Local variable
char answer;
cout<<"Would you like to re-run? (Y/N) ";
cin>>answer;
cin.ignore(100,'\n');
if(answer == 'Y' || 'y')
{
return true;
}
if(answer == 'N' || 'n')
{
return false;
}
}
...
do
{
menu(gameamount,response);
if (response == 1)
{
inputs(gameamount, game_count);
writeout(gameamount);
}
if (response == 2)
{
outputs(gameamount, game_count);
}
}while(again());
return 0;
}
I tried using else and else if and returning false after the first if-statement but that still did not work, I can't put the block of code in main to conserve space so I have to create a boolean function to ask the user to re-run the program.
There's a logic error in your code.
Try this:
if(answer == 'Y' || answer == 'y')
{
return true;
}
if(answer == 'N' || answer == 'n')
{
return false;
}
You should also possibly output a message in case the user decides to type something other than 'Y','y','N' or 'n'.
Also, I'm not 100% sure about this, but I think that your code is always returning true in the first if statement because you are checking to see if 'y' is true, which I think it always is.
if(answer == 'Y' || 'y')
{
return true;
}
Any value other than 0 would equate to true, and the character 'y' when treated as an integer is equal to it's corresponding ASCII code (121 in this case).
Try to replace the line
if(answer == 'Y' || 'y')
by
if(answer == 'Y' || answer == 'y')
The line
if (answer == 'Y' || 'y')
will enter the if block in every case, since it won't evaluate to what you intended. It evaluates answer == 'Y' which is true or false, but then ORs this value with 'y'. In this step, 'y' is converted to a boolean value in order to be ORed logically, and since all numbers unequal to 0 are converted to true the whole expression is always true.
If you correct this to
if (answer == 'Y' || answer == 'y')
you still have the following problem:
Your function only returns a value in the case where the user enters either a Y or an N in lower or upper case. But what if the user enters an invalid letter? You need to define a behavior for this situation. Currently your program doesn't have a return statement for this case, resulting in undefined behavior, which means the result of the function can be anything.
You can either return a default value (e.g. false), then you need to remove the second conditional if but keep the return false.
Another solution is to loop until the user entered a valid value.