Why is this an infinite loop using || logical operator
char c;
std::cin >> c;
while( c != 'y' || c != 'Y' || c != 'N' || c != 'n')
but this is not
while( c != 'y' && c != 'Y' && c != 'N' && c != 'n')
I don't understand why && operator work here because logically thinking || operator is better fit.
Lets just look at the very smallest part:
c != 'Y' || c != 'N'
If c is 'Y' then it is not 'N', if it is 'N' then it is not 'Y'. Aka:
c | c != 'Y' || c != 'N'
Y | 1 || 0 = 1
N | 0 || 1 = 1
? | 1 || 1 = 1
If your logic always returns 1 no matter what, the loop will run forever. I assume you are looking to wait until you get c as one of these values, so write it logically.
I want to wait until c is one of ['y', 'Y', ...]
And you might be able to write some nicer code:
std::array<char> options = {{'y', 'Y', 'n', 'N'}};
while (std::none_of(std::begin(options), std::end(options),
[&c](char check) { return check == c; };)) {
std::cout << "Hey write the correct character!\n";
}
Untested!
You are checking the condition which is always true by using || operator,
( c != 'y' || c != 'Y' || c != 'N' || c != 'n')
This is always true ,because it would always satisfy at-least 3 conditions in your conditional statement .
if your char is n then it would satisfy remaining conditions
c!='y' , c!='Y' , c!='N' and similarly for any other character
Related
This question already has answers here:
Most efficient way to compare a variable to multiple values?
(7 answers)
Why is if statement not working [duplicate]
(2 answers)
Closed 11 months ago.
I'm 100% sure from testing that for loop does iterate through characters how is it suposed to, but the other part of the program isn't working correctly.
Im trying with if statement to print only uppercase characters.
Here are some input/output samples to get a better pitcure what this program is about:
Input: Tim-Berners-Lee Output: TBL
Input: Albert-Einstein Output: AE
Here is the code:
#include <iostream>
#include <string>
using namespace std;
int main(){
string name;
cin >> name;
int N = name.length();
for (int i = 0; i < N; i++)
{
if (name[i] == 'A' || 'B' || 'C' || 'D' || 'E' || 'F' || 'G' || 'H' || 'I' || 'J' || 'K' || 'L' || 'M' || 'N' || 'O' || 'P' || 'Q' || 'R' || 'S' || 'T' || 'U' || 'V' || 'W' || 'X' || 'Y' || 'Z'){
cout << name[i];
}
}
}
Your code will calculate compare name[i] == 'A' first and then take
the result to do OR operation with 'B', 'C', and so on..., which absolutely won't work.
You should do name[i] == 'A' || name[i] == 'B' || ... or just use std::isupper().
I have tried writing a loop that would refrain the user to enter a wrong kind of data (actually a boolean) into the program by using the || operator.
int Entrer()
{
int A;
do
{
cout<<"Entrez 0 ou 1."<<endl;
cin >> A;
}
while (A != (1 || 0));
return A;
}
Can somebody tell me why the program only accepts 1 and no 0 ?
do { ... } while (A != (1 || 0));
It should be while (A != 1 && A != 0);
Otherwise, A != (1 || 0) stands for A != 1 since (1 || 0) is evaluated before !=.
If you want to accept 1 and 0, you need to write the conditional as while(A != 1 && A != 0);. As your conditional written, it will evaluate the (1 || 0) first, and, as 1 is true and 0 is false, will evaluate to A != 1.
here's a simple logic error I can't quite wrap my head around:
Why does the following statement always equate to true?
if ( (grid[i][0] && grid[i][1] && grid[i][2]) == ('X' || 'x') ) return true;
It works flawlessly for
if ( (grid[i][0] && grid[i][1] && grid[i][2]) == ('X') return true;
Do it like this:
create a function to check a character of being x:
bool isX(char c)
{
return c == 'X' || c == 'x';
}
and the you can write:
if ( isX(grid[i][0]) && isX(grid[i][1]) && isX(grid[i][2]))
return true;
That's because the expressions
'X' || 'x'
and
grid[i][0] && grid[i][1] && grid[i][2]
use the || and && operators between non-zero integer-typed values (because char is an integer type) and so they both evaluate to true.
To translate into C++ (or almost any other somewhat similar language, for that matter) that you want characters x, y and z to be equal to either of the characters c and C, you must compute
(x == c || x == C) && (y == c || y == C) && (z == c || z == C)
so apply that to your problem.
More importantly though, learn about boolean operators and programming in general before you try to tackle C++.
In the first case, it returns true because none of the grid elements has the value of zero. The && operator produces 0 or 1, depending on the values that you pass.
In the second case, it does not work as expected either: you wouldn't get an 'X' by &&-ing values together.
The proper way of checking if three items are equal to 'X' or not would be as follows:
if (toupper(grid[i][0]) == 'X'
&& toupper(grid[i][1]) == 'X'
&& toupper(grid[i][2]) == 'X') {
return true;
}
To generalize the concept of "win" in TiCTacToe, write a function that returns true when a sequence of three items with a specific step in each direction holds a sequence of a given character, like this:
bool isWin(int r, int c, int dr, int dc, char ch) {
return toupper(grid[r+0*dr][c+0*dc] == ch
&& toupper(grid[r+1*dr][c+1*dc] == ch
&& toupper(grid[r+2*dr][c+2*dc] == ch;
}
bool isWin(char ch) {
return isWin(0,0,0,1,ch)
|| isWin(0,0,1,0,ch)
|| isWin(1,0,0,1,ch)
|| isWin(0,1,1,0,ch)
|| isWin(2,0,0,1,ch)
|| isWin(0,2,1,0,ch)
|| isWin(0,0,1,1,ch)
|| isWin(2,0,-1,1,ch);
}
In my introductory computer science class, a prompt asked us:
"Given a char variable c that has already been declared , write some code that repeatedly reads a value from standard input into c until at last a 'Y' or 'y' or 'N' or 'n' has been entered."
The code I entered causes an infinite loop, but the logic makes sense to me. Can somebody please explain why the following Boolean expression is faulty?
while (c != ('n' || 'N' || 'y' || 'Y'))
cin >> c;
Because that expression does not do what you think it does. The correct is
while (c !='n' && c != 'N' && c!= 'y' && c != 'Y')
But what happens with the one you present above?
('n' || 'N' || 'y' || 'Y')
This is a series of 4 boolean ORs. The first one is 'n' || 'N', where the chars 'n' and 'N' are converted to booleans (both true), therefore the whole expression is true.
So you are left with
while (c != true)
which is the same as c != 1, and goes into a loop until you input the character with ASCII value 1. Since that is not a printable character, no input from the keyboard is going to get you out of the loop.
This:
while (c != ('n' || 'N' || 'y' || 'Y'))
is equivalent to:
while (c != true )
because any group of values ORd together is going to evaluate to true when one or more of them is non-zero. What you're probably looking for is:
while ( c != 'n' && c != 'N' && c != 'y' && c != 'Y' )
The condition in your loop is incorrect.
The correct condition is:
while ( c != 'n' && c != 'N' && c != 'y' && c != 'Y' )
{
// ...
}
When you write:
while (c != ('n' || 'N' || 'y' || 'Y'))
You ask if c is different from ('n' || 'N' || 'y' || 'Y'). But this expression itself will be evaluated as true because non-zero values ORd together are always evaluated as true. So your condition is equivalent to:
while( c != true )
Wich will lead to an infinite loop...
Try
while (c !='n' && c!='N' && c!= 'y' && c!='Y')
cin >> c;
You are "OR"ing 'n','N','y','Y' which always equals to true ( non zero). This is reason The loop is not terminating.
The result prints out 'c' 3 times, anyone know why it always meets the first condition?
#include <iostream>
using namespace std;
char x(char y)
{
if (y == 'a' || 'b')
{
return 'c';
}
else if (y == 'c' || 'd')
{
return 'e';
}
else
{
return 'g';
}
}
int main()
{
cout << x('a') << endl;
cout << x('c') << endl;
cout << x('p') << endl;
return 0;
}
You need something of the form
if (y == 'a' || y == 'b')
This is because in this expression
(y == 'a' || 'b')
you are evaluating an OR of y == 'a' and 'b', and since 'b' evaluates to true by virtue of being non-zero, the whole expression evaluates to true.
(y == 'a' || true)
This line:
if (y == 'a' || 'b')
is equivalent to:
if ((y == 'a') || ('b'))
That's because the == operator has higher precedence than the || operator.
Since 'b' is non-zero, it always evaluates as true, and so (y == 'a' || 'b') always evaluates as true.
You need to write this:
if (y == 'a' || y == 'b')
Of course, even if the precedence was the other way around,
if (y == ('a' || 'b'))
would not have been what you intended either!
Please check the operator precedence (priority) here: http://en.cppreference.com/w/cpp/language/operator_precedence
In your case the condition expression is:
(y == 'a' || 'b')
So the “y == 'a'” part is evaluated first which may be true/false depending on the value of "y". Let's call the value of "y=='a'" as "t". And then the expression is evaluated as " t || 'b'" in this case 'b' is actually the ASCII code value of character 'b' (98) which is surely larger than 0, so the result of the boolean expression is always true.
To dismiss any ambiguity caused by operator precedence, I think it's a good habit to use brackets to explicitly express your priority in the evaluation. In your case, as suggested by earlier post, it should be:
if ((y=='a') || (y=='b'))