简体   繁体   中英

Composition of OR statements does not yield the correct boolean value when comparing strings

I have the following code:

void funct(string m){
    if (m != "s" || m != "l" || m != "r" || m != "S" || m != "L" || m != "R") {
        //Do something
    }
}

When passed value "r" the conditional body should not be executed, due to m.="r". Anyways "Do something" is executed.

On the other side when testing the following statement

void funct(string m){
    if (m != "r") {
        //Do something
    }
}

Given m = "r" the function works as intended.

On the other hand, if use the == operator instead of:= I get the correct composite value:

if (!(m == "l" || m == "l" || m == "r" || m == "S" || m == "L" || m == "R")) {
    //Do something
}

This works just fine.

Did anybody else have similar issues? Or explain the "misbehavior" of the first chunk of code.

Lang standard C++14

Grateful in advance

It's surprising that you can spell out the problem so clearly and yet not see the mistake you are making

if (m != "s" || m != "l" || m != "r" || m != "S" || m != "L" || m != "R") {
    //Do something
}

'Do something' will be executed if EITHER m.= "s" OR if m.= "l" OR....

Since every string in the world is either not equal to "s" or not equal to "l" then 'do something' will always be executed. Think about it, "s" is not equal to "l" and "l" is not equal to "s" and every other string is not equal to both of them.

The code you really want is this

if (m != "s" && m != "l" && m != "r" && m != "S" && m != "L" && m != "R") {
    //Do something
}

To be fair this is an extremely common mistake to make in logic.

You can use the C++ standard library functions to reduce mistakes. std::none_of from the algorithm header works great in this situation. If your string matches none of the other strings, it will return true.

#include <algorithm>

void funct(const string& m) {
    const string tokens[] = {"s", "l", "r", "S", "L", "R"};
    auto compare = [&m](const string& token) { return m == token; };
    if (none_of(begin(tokens), end(tokens), compare)) {
        //Do something
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM