Why does this if statement not behave as I'd expect? - c++

I am making a program that will evaluate the value of something. I have a variable that holds the total value to be added, rcoverE. When I test "y" for the second question, it works, but when I put in "n", it adds 5 anyway. Why is this happening?
#include <iostream>
using namespace std;
int main(){
int year, yearE, rcoverE;
string rcover, func;
cout << "Enter the decade your thing was produced (eg. 20):";
cin >> year;
cout << "Does you typewriter have original thingy? (y,n):";
cin >> rcover;
rcoverE = 0;
if(rcover == "y" || "Y"){
rcoverE = rcoverE + 5;
}else{
rcoverE = rcoverE + 0;
}
cout << rcoverE;
yearE = 100 - year / 2;
}

if(rcover == "y" || "Y"){
This condition is wrong it should be:
if(rcover == "y" || rcover == "Y"){
This: if(rcover == "y" || "Y"){ is logically equivalent to if(rcover == "y" || "Y" != 0) and "Y" != 0 is always true.

if(rcover == "y" || "Y")
Does not evaluate the way you think it does. This actually evaluates as if ("rcover == 'y') or if('Y')", not "rcover == ('y' || 'Y')." In some languages the compiler would not let you do this, but in C++, simply putting in the statement "Y" returns true. You need to change the statement to:
if(rcover == "y" || rcover == "Y")

Related

why wont this do while loop exit after accepting input

Pretty straight forward. i dont understand why it wont quit the loop after not accepting a y char.
ive tried different variations of == and != with regards to y char and n char
vector<int> v;
char ans;
do
{
cout << "Enter scores, enter number outside of 0-100 to stop:\n";
get_scores(v);
print_stats(v);
cout << "Do you want to try another set of scores? Y/N: \n";
cin >> ans;
} while (ans != ('n' || 'N'));
after typing any char, the loop keeps asking for more input.
NOTE: the get scores and print stats functions work as their supposed to.
Your comparison in the while condition is not correct, you probably meant to do
while (ans != 'n' && ans != 'N');
('n' || 'N') will be coerced to true (1), so you would check for a char of value 1 instead of 'n' / 'N'
} while (ans != ('n' || 'N'));
Here you are comparing char with boolean result of || operation for the 2 other chars.
Which alway evaluates as true.
So your while statement is effecitvely
} while (ans != true);
to fix this you need to compare ans to both of the n and N and exit if one of them becomes true, for example:
} while ((ans != 'n') && (ans != 'N'));
while (ans != ('n' || 'N')) is the same as writing while (ans != (true)). You probably wanted while ((ans != 'n') && (ans != 'N')).

Char equals char undesired output [duplicate]

This question already has answers here:
if statement not working right?
(5 answers)
Can you use 2 or more OR conditions in an if statement? [duplicate]
(9 answers)
Closed 4 years ago.
I am trying to create a simple c++ program which prints out if char is Y or y, N or n or neither.
After debugging I have found out that the if(chr == 'Y' || 'y') statement is true even though char variable is 'N'. Can anybody tell me why this if statement is true and not false?
#include "pch.h"
#include <iostream>
using namespace std;
void main()
{
char chr = 'N';
if (chr == 'Y' || 'y')
{
cout << "chr is y" << endl;
}
else if (chr == 'N' || 'n')
{
cout << "chr is n" << endl;
}
else
{
cout << "chr is something else" << endl;
}
}
This is not doing what you thing:
if (chr == 'Y' || 'y')
This is basically:
if (chr == 'Y' || true)
So in the end:
if (true)
You have to say what you compare:
if (chr == 'Y' || chr == 'y')
The operator == only takes one character, not a set of possible characters.
Instead of this
if (chr == 'Y' || 'y')
You need
if ((chr == 'Y') || (chr == 'Y'))
Likewise for the 'N' and 'n'.
It is also possible do it with one comparison:
if (toupper((unsigned char)chr) == 'Y')
This way, maintainability is slighly improved as only one value has to be changed should the letter change (for a different localization, per example).

Unknown behaviour of OR operator in C++ [duplicate]

This question already has answers here:
How to compare multiple strings inside an if statement?
(6 answers)
Closed 4 years ago.
I have this code running by chance and when i put anything as the answer it is showing me correct. I know we have to put ans before YES and yay, but this code was compiled too, as i mentioned if i put any word as the input the output is correct:
string ans;
cin >> ans;
if(ans == "yes" || "YES" || "yay") {
cout << "Correct";
}else {
cout << "Incorrect";
}
Ok here's the precedence (L->R) and associativity of logic wise operators:
(((ans == "yes") || "YES") || "yay")
Since C/C++ has no chaining unlike Python.
1st: ans == "yes" -> str to str comparison
2nd: bool result of 1st || "YES" -> bool and str comparison = always true for "YES" is not null
3rd: true || "YES" = always true
Thus, the condition will always be true for "YES" and "yay" are not null.
You have the precedence wrong.
if (var == A || B || C) means "if (var is equal to A) OR (B is not zero) OR (C is not zero)"
You want to do if (var == A || var == B || var == C). That means "if (var is equal to A) OR (var is equal to B) or (var is equal to C)"
You should compare ans with each value. Every comparison with value is not "0" or "fail" value is assumed as "true". So if you input the if a condition like if("yes") it always returns a true.
int main()
{
std::string ans;
std::cin >> ans;
if("yes" == ans || "YES" == ans || "yay" == ans)
{
std::cout << "Correct\n";
}
else
{
std::cout << "Incorrect";
}
}

How to use the or statement (||) correctly, in an else-if statement

Consider this code:
string GameExit;
bool GameChoiceGo = true;
while (GameChoiceGo == true)
{
system("cls");
cout << "\n Are you sure you want to exit? (Yes or No) ";
cin >> GameExit;
if (GameExit == "y" || "Y" || "yes" || "Yes" || "YES")
{
cout << "User typed Yes";
Sleep(3000);
system("cls");
break;
}
if (GameExit == "n" || "N" || "no" || "No" || "NO")
{
cout << "User typed No";
Sleep(3000);
system("cls");
GameChoiceGo = false;
}
else
{
cout << "\nI'm sorry but, " << GameExit << " is not a acceptable choice. Type: Yes or No.\n\n\n";
Sleep(3000);
system("cls");
}
}
break;
Here, only the first statement is activated. Even if the user types "No" or anything else, it will output "user typed yes".
The else-if statements work if I replace the or statements with only one statement (i.e. "y" and "n"). The only problem is, I want to have any possible version of yes and no that the user might type in the code.
Any ideas why the code is not working correctly?
I'm sorry, but you have to write GameExit == for every condition you want to check:
if (GameExit == "y" || GameExit == "Y" || GameExit == "yes" || GameExit == "Yes" || GameExit == "YES")
If you write if ("y") (which is basically what you are doing, only with more statements), the const char[] will decay to a const char*, and that pointer will be compared to 0. Now, that pointer will never be null, as there will always be memory allocated for the string literal.
A better solution is to (1) make an array with all the options, so that checking the conditions becomes a simple search or (2) convert the input to all lowercase for example, and compare that.
// 1)
std::vector<std::string> options = { "y", "Y", "yes", "Yes", "YES" };
if (std::find(options.begin(), options.end(), GameExit) != options.end());
// or
if (std::any_of(options.begin(), options.end(), [&GameExit](const auto& value) {
return GameExit == value;
});
// 2)
std::transform(GameExit.begin(), GameExit.end(), GameExit.begin(), ::tolower);
if (GameExit == "y" || GameExit == "yes");
You can look up the functions if you do not know what they do :).
Correct way using OR operator in "your" code is as below (note the explicit use of == statements between || operators):
if (GameExit == "y" || GameExit =="Y" || GameExit =="yes" || GameExit =="Yes" || GameExit =="YES")
{
cout << "User typed Yes";
Sleep(3000);
system("cls");
break;
}
if (GameExit == "n" || GameExit =="N" || GameExit =="no" || GameExit =="No" || GameExit =="NO")
{
cout << "User typed No";
Sleep(3000);
system("cls");
GameChoiceGo = false;
}
PS: The above answer is not intended to give the best programming practice in a similar situation but to give the specific answer to the OP with the minimal code change :)
// -----
EDIT: Here is a better approach using STL. Note that (unsorted) array lookup requires linear search, whereas unordered_set, which is a hash set, has (on average) constant time lookup. This will be faster especially when the yes, no etc. options are plenty.
#include <unordered_set>
...
// These sets can be as large as possible or even dynamically
// updated while the program is running. insert, remove, lookup will
// all be much faster than a simple array.
unordered_set<string> ySet{"y", "Y", "yes", "Yes", "YES"};
unordered_set<string> nSet{"n", "N", "no", "No", "NO"};
if (ySet.find(GameExit) != ySet.end())
{
cout << "User typed Yes";
Sleep(3000);
system("cls");
break;
}
if (nSet.find(GameExit) != nSet.end())
{
cout << "User typed No";
Sleep(3000);
system("cls");
GameChoiceGo = false;
}
...
You need to define a complete equality for each expression like this:
if ( gameExit == "y" || gameExit == "Y" ) {}
GameExit == "y" || "Y" || ....
is incorrect. The correct method is:
GameExit == "y" || GameExit == "Y" || ....
and so on, both for the yes or no case.

If statement always executing even when the condition is false?

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).