【问题标题】:while loop runs even if condition isnt true即使条件不成立,while 循环也会运行
【发布时间】:2019-07-06 04:06:06
【问题描述】:

我正在尝试使用 c++ 制作计算器,我正在尝试实现错误处理,因此如果用户输入非算术运算符,它将告诉用户请使用 while 循环输入运算符。问题是,即使用户在第一次运行时输入运算符,while 循环仍然会执行。

我试过不在while和perinthesis之间加空格,我也试过不使用变量,只放所有条件来触发循环。

string getop()
{
  string op;
  int check = 1; 
  cout << "Enter an operator (+ - / *): ";
  cin >> op;
  if ((op != "+") || (op != "-") || (op != "/") || (op != "*"))
  {
    check = 0;
  }
  while (check == 0) // while the input is not a valid operator
  {
    cout << "Invalid operator, please enter a valid operator: ";
    cin >> op;
    if ((op == "+") || (op == "-") || (op == "/") || (op == "*"))
      check = 1;
  }

  return op;
}

问题是,即使用户在第一次运行时输入了一个运算符,while 循环仍然会执行。

【问题讨论】:

  • if ((op != "+") || (op != "-") || (op != "/") || (op != "*")) 这个比较是错误的。其中至少有 3 个总是正确的,所以如果你将它们 or 放在一起,你每次都会得到 true。像第二次那样做。让check0 开始,然后执行if ((op == "+") || (op == "-") || (op == "/") || (op == "*")),看看你是否应该把它放到1
  • @Blaze 真可惜。目前仅此评论的解释就超过了 2/3 的答案。要是你把这个作为答案就好了,这样它就可以被识别出来了。
  • if (!...) 后跟 while (!...) 可以简单地替换为 do { } while (!...);。这样可以防止代码重复。
  • 这并没有解决问题,但代码不需要所有这些括号。 if (op == "+" || op == "-" || op == "/" || op == "*") 工作得很好。 == 的优先级高于 ||,这确实是唯一有意义的事情。
  • @scohe001 感谢您的认可。我很着急,所以我没有时间详细回答,但现在看来当前的答案很好而且很详细。

标签: c++


【解决方案1】:

试试:

(op != "+") && (op != "-") && (op != "/") && (op != "*")

运算符||or 运算符(另一种选择,一个或另一个就足够了)。您需要运算符&amp;&amp;,它强制所有条件一起为真。

【讨论】:

  • 非常感谢您的回复,我不敢相信我错过了这个
  • @berg95 - 如果你继续编程,请放心,你会做很多比这更愚蠢的事情。在第一个十年左右之后,您会习惯于问“我怎么会这么笨?”
【解决方案2】:

你有一个逻辑错误:

if ((op != "+") || (op != "-") || (op != "/") || (op != "*"))

无论op 是什么,这总是会产生true

你想要:

if ((op != "+") && (op != "-") && (op != "/") && (op != "*"))

一个非常好的做法是命名您的逻辑事件。此外,AND 链式否定相当不直观(而且也不可读)。所以更好的选择是:

bool is_valid = (op == "+") || (op == "-") || (op == "/") || (op == "*");

if (!is_valid)
    check = 0;

您也不应该use namespace std; - 您可以阅读here 为什么。

【讨论】:

  • 为什么创建另一个(不需要的)局部变量更好? (另请注意,您不小心将 OR 留在了该新代码中)
  • @scohe001 大幅提高可读性。这被认为是好的做法。并且 OR 是故意的,因为这是积极的情况。
  • 啊,我的错,我看错了。请注意,在 while 循环中将再次检查相同的条件语句,因此无论如何您最终都不得不再次复制此代码。我仍然认为没有任何 if 和 int 变量的 while(op != "+" &amp;&amp; op != .... ) { 会更干净。但对每个人来说都是他们自己的。
  • 感谢您的回复,现在我不会再使用命名空间了,我已经解决了这个问题
  • @scohe001 我也是这么想的,但我经常收到一条评论说人们总是要为他们的事件命名。喜欢评论here
【解决方案3】:

您想使用 AND (&amp;&amp;),而不是 OR (||):

if ((op != "+") && (op != "-") && (op != "/") && (op != "*"))
{
  check = 0;
}

【讨论】:

  • 虽然这段代码可以解决问题,但如果解释一下它的作用方式/原因,答案会好得多。请记住,您的答案不仅适用于提出问题的用户,还适用于所有其他找到该问题的人。
【解决方案4】:

你的问题就在这里:

if ((op != "+") || (op != "-") || (op != "/") || (op != "*"))
{
    check = 0;
}

假设op 被赋值为"+",这意味着这些条件都为真:op != "-"op != "/"op != "*"

由于您使用的是 OR (||) 运算符,如果 任何 条件为真,check 将被分配一个值 0。事实上,无论op 具有什么值,这四个条件之一总是为真。

您应该改用 AND (&amp;&amp;),以便在所有条件都为真时将 check 分配为 0:

if ((op != "+") && (op != "-") && (op != "/") && (op != "*"))
{
    check = 0;
}

【讨论】:

    【解决方案5】:

    当您有一个由&amp;&amp; 加入的断言链时,通常否定包括否定所有断言并将所有&amp;&amp; 运算符更改为||,反之亦然。

    您更改了所有断言,否定了它们,但您忘记将|| 更改为&amp;&amp;

    在 Google 中查找德摩根定理。

    【讨论】:

      猜你喜欢
      • 2017-04-10
      • 2021-02-07
      • 2021-08-07
      • 1970-01-01
      • 2016-03-14
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多