使用逻辑NOT,!,而不是使用它

时间:2013-09-03 18:30:45

标签: c++

我有一个从文件中读取行的函数,并将每行中的每个字符串存储在向量中。

void openf(std::string s)
{
std::string line;
std::string b;
std::ifstream in;
in.open(s);
std::vector<std::string> vec;
if(in.is_open()) {
    std::cout << "File is open\n" << std::endl;
    while(std::getline(in,line)) {
        for(decltype(line.size()) i = 0; i != line.size(); ++i) {
            if(isspace(line[i]) || ispunct(line[i])) {
                vec.push_back(b);
                b = "";
            }
            else {
                b += line[i];
            }
        }
    }
}
for(auto a:vec)
    std::cout << a << std::endl;
in.close();
}

这个工作。

但如果我这样做

if(!isspace(line[i]) || !ispunct(line[i])) {
    b += line[i];
}
else {
    vec.push_back(b);
    b = "";
}

什么都没打印。

如果我没有逻辑OR语句,只需单独使用!isspace和!ispunct,程序的行为就像它在相应情况下所期望的那样。

我认为我不需要,但我也尝试在每个操作员周围放置(),这样就不会互相干扰。仍然行不通。

看起来像是相同的代码。为什么它不会在一个案例中起作用而在另一个案例中起作用呢?

4 个答案:

答案 0 :(得分:13)

你有:

if (A || B)
    do this
else
    do that

要否定这一点,你需要:

if (!(A || B))
    do that
else
    do this

!(A || B)(!A && !B)

致谢

所以你需要写

if (!isspace(line[i]) && !ispunct(line[i]))

有关详细信息,请参阅DeMorgan's Laws

答案 1 :(得分:5)

参考 - De-Morgan's Law

||更改为&&

(!A && !B) = !(A || B)

所以使用,

(!isspace(line[i]) && !ispunct(line[i]))
                   ^^

以你的第二种方式

答案 2 :(得分:3)

这不是您在工作代码中检查的条件的反转。这是:

if(!isspace(line[i]) && !ispunct(line[i])) {
  b += line[i];
}
else {
  vec.push_back(b);
  b = "";
}

! isspace(x) || ! ispunct(x)始终为true。一个空间不会是标点符号;惩罚不会成为太空。

答案 3 :(得分:1)

应该是:

if( !(isspace(line[i]) or ispunct(line[i])) )
    b += line[i];
else {
    vec.push_back(b);
    b = "";
}

请参阅this post