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.
Related
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 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' )
when it gets to this if statement, no matter what 'option' is inputted its always setting if(option == "y" || "Y") condition to true?
bool UserInterface::readInConfimDeletion() const
{
string option = "";
cout << "Are you sure you want to delete these transactions? Y/N ";
cin >> option;
if (option == "y" || "Y")
{
return true;
}
else if (option == "n" || "N")
{
return false;
}
else{
readInConfimDeletion();
}
}
You can't compare multiple conditions like this:
if (option == "y" || "Y")
The "Y" condition will evaluate to true always if evaluated.
you need to do this:
if (option == "y" || option== "Y")
It would be simpler IMO to uppercase the string and perform a single comparision, there are a number of options to do this: Convert a String In C++ To Upper Case
So a possible solution would be:
#include <boost/algorithm/string.hpp>
string upperStr = boost::to_upper_copy(option);
then you can do:
if (upperStr == "Y")
Change it like this:
if (option == "y" || option == "Y")
and similarly
else if (option == "n" || option == "N")
You cannot compare multiple strings like the way you are doing.
You need to say option == "y" || option == "Y" etc..
FYI / if (option == "y" || "Y") is actually asking if option == "y" or... "Y" itself is true, and "Y" is a string literal that undergoes a Standard Conversion to const char* then - being used inside an if undergoes a further conversion to the bool true (because the pointer is not nullptr, it's deemed true).
I'm just stuck on some logic statements.
specifically the ones that are in the function char GetInteger() so how would I only allow 3 values to cause the loop to exit.
char GetInteger( /* out */ char& usrinput)
{
do
{
cin >> usrinput;
cin.ignore(200,'\n');
if (usrinput != 0 || usrinput != 1 || usrinput != 2)
{
cout << "Invalid Input." << userinput << " Try Again\n";
}
} while(usrinput != 0 || usrinput != 1 || usrinput != 2);
return userInput;
}
Two issues with this code:
First userinput has a type of char. So when you read from a stream you read a single character (after dropping white space). So when a user types 1<enter> you get the character '1' in the variable userinput. Note the character '1' is not the same as the number 1.
Thus your test should be:
userinput != '1';
Secondly your boolean logic is wrong. When first learning it is sometimes easier to state the problem as a list of values that you would like to be acceptable (not the unacceptable ones).
You want the conditions to be false if the userInput has one of your accepted values (any good value will fail the test and thus not invoke the bad code). The first step to this is to get a true if any of your values are valid.
// If any value is good then true.
userinput == '1' || userinput == '2' || userinput == '3'
To invert this just add a not to the expression.
if (! (userinput == '1' || userinput == '2' || userinput == '3') )
Note: in boolean logic
!(A || B) => (!A && !B)
So you could re-write the above as:
if (userinput != '1' && userinput != '2' && userinput != '3')
I think this was your main mistake you converted the == into != but did not convert the || into &&.
I would also suggest that you could simplify this (as you may get more valid result) byconverting this into a range based test.
if (userinput < '1' || userinput > '3')
{
// Test Failed.
}
Additionally. Since you have the test in two places. You should yank it outinto its own function. Then you can call the function to do the test.
bool isUserInputValid(char userInput)
{
return userInput >= '1' && userInput <= '3';
}
Now we can re-write your original function as:
char GetInteger( /* out */ char& usrinput)
{
do
{
cin >> usrinput;
cin.ignore(200,'\n');
if (!isUserInputValid(userinput))
{
cout << "Invalid Input." << userinput << " Try Again\n";
}
} while(!isUserInputValid(userinput));
return userInput;
}
First of all, you should use int instead of string as you are reading integer.
You can use while(1) instead of putting condition in while. Inside while loop, if your selection is 0 or 1 or 2, you can simply break the loop.
I'm trying to write a calculation program that, when it has run through once asks the user if they wish to make another calculation. This has the form of a separate function that is called at appropriate points in the main function:
char repeatcalc(char y){
cout << "Would you like to perform another calculation? [Y]es/[N]o" << endl;
cin >> y;
if(y == 'Y' || y == 'y'){
return y == 'y';
}
else if(y == 'N' || y == 'n'){
return y == 'n';
}
else{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
repeatcalc(y);
}
}
The idea being, the user hits a button and the function returns either a 'y', an 'n' or repeats itself. This then feed back into a while loop in the main function that repeats if a 'y' is returned and ends if an 'n' is returned.
The repeat section in the function above works in the main code, as does the 'y' return, but when 'n' is selected, it seems to return a 'y' anyway.
I'm missing something obvious, but I can't figure out quite what! Any suggestions?
Thanks.
Convert your function to return a bool. For example:
if (y == 'Y' || y == 'y') return true;
if (y == 'N' || y == 'n') return false;
...
return repeatcalc() ;
being y a local char variable. This way the function dont need an argument. And you can ask simple if (repeatcalc() ) reapeat;
Also, pay attention: == is for comparing and return a bool, while you are trying to make an assingment: return y='y'; with in this case is just return 'y';