0

I have run into a strange to me problem. For some reason multiple || statements, even divided by commas and parenthesis will not work. The last thing I expected to work is the & statement, which requires for both conditions to be met, but in my case it works for one condition as if it was an OR statement.

Someone please explain to me why is this happening. I am very confused.

WORKS:

#include<iostream> 
#include<vector>
#include<string>

using namespace std;


int main()
{
string quest;

quest = "Where is my dog?";

string::iterator m;
vector<string>question;

string t;

for(m = quest.begin(); m != quest.end(); m++)
{
    if(*m != ' ' & *m != ',' & *m != '?' & *m != '.') //works with & and &&

    {
        t.push_back(*m);
    }
    else
    { 
        cout << t << endl;
        question.push_back(t);
        t.clear();
    }
}
}

Does not work:

#include<iostream> 
#include<vector>
#include<string>

using namespace std;


int main()
{
string quest;

quest = "Where is my dog?";

string::iterator m;
vector<string>question;

string t;

for(m = quest.begin(); m != quest.end(); m++)
{
    if(*m != ' ' || *m != ',' || *m != '?' || *m != '.')    // DOES NOT WORK
    {
        t.push_back(*m);
    }
    else
    { 
        cout << t << endl;
        question.push_back(t);
        t.clear();
    }
}
}
jww
  • 97,681
  • 90
  • 411
  • 885
VSB
  • 232
  • 1
  • 4
  • 13
  • What do you expect the second one to output and what does it output? – Daniel Nov 07 '11 at 00:28
  • Answerers, please state both 1) what is going on, and 2) how to do it right. I won't vote for half an answer. – Mike DeSimone Nov 07 '11 at 00:34
  • 1
    I wish people didn't down vote me for asking something I didn't understand, even if it was something extremely silly. – VSB Nov 07 '11 at 01:59
  • 3
    I agree... this is a good question, it has a minimal example, the question is clear and specific, regardless of the OPs "skill" in the subject, this should not be a factor... shame on those down-voters - I call it bullying of a kind (so +1 for a good question) – code_fodder Sep 12 '17 at 08:00

4 Answers4

7
if(*m != ' ' || *m != ',' || *m != '?' || *m != '.')    // DOES NOT WORK

What would you expect that to do? You're asking whether something is not A or not B. Either one of those is always true (as long as A and B are not the same thing), so your expression as a whole is always true.

It looks like you might want:

if(*m != ' ' && *m != ',' && *m != '?' && *m != '.')

That condition will be true if *m is anything other than space, comma, question mark, or period.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
3

You should use && for logical "and".

& operator is for bitwise "and", which in your case produces true since all the characters in the statement have at least one common bit lit.

What is it that you're trying to do?

Note, that if the intention is to filter out " ,?." characters, then the right thing to do is to use && because || will not do that (because each character will fit at least one, so you will never get into the else clause, always go to then).

littleadv
  • 20,100
  • 2
  • 36
  • 50
  • it can be done with or, you ask if they are equal or equal and invert the match at the end, of course it's it's relatively easy to prove that NOT OR that this is the same as AND of NOT inputs. – ewanm89 Nov 07 '11 at 00:36
  • True, if the question is `==`, then the operator should be `||`. – littleadv Nov 07 '11 at 00:39
1

Or looks at the first if it doesn't match it goes onto the next one and checks it else it executes the code. So if m is ' ' it'll fail the first test, but the second test will pass as ' ' is not ','.

I expect what you actually want is something along the lines of:

if (!(*m == ' ' || *m == ',' || *m == '?' || *m == '.'))
ewanm89
  • 919
  • 5
  • 22
  • 1
    @TechnoViking - this is an example of the classic logic transformation: (m != x) && (m != Y) is always equivalent to: ! ( ( m == X ) || ( m == Y ) ). Read up on Boolean algebra, Wikipedia has an article. – casualcoder Nov 07 '11 at 01:46
  • @casualcoder thank you! the problem was that I looked at it only from when the conditions were true, sometimes we tend to get stuck on one thing and fail to analyze properly, something I do frequently – VSB Nov 07 '11 at 01:55
1

You should be using && over & as && is a logical operator where & is a bitwise operator.

When it comes to if tests, you need to remember how the operators work.

Using logical OR (||) means that if one of the conditions is true then the whole statement is true.

Using logical AND (&&) means that if all of the conditions are true then the whole statement is true.

See this page for help on C++ operators. About half-way down is the section on Logical and Bitwise operations.

Edit: Hopefully this code example will help clear up your confusion:

int A = 0;
int B = 1;

if (A == 0 && B == 0) {
  //This code will not run, as the whole statement is false
  . . . .
}

if (A == 0 && B == 1) { 
  //This code will run, as the whole statement is true
  . . . .
}

if (A == 0 || B == 0) {
  //This code will run, as A = 0, so the whole statement is true
  . . . .
}
Deco
  • 3,261
  • 17
  • 25