为什么这个程序需要3行输入?

时间:2016-04-10 16:39:10

标签: c++

我正在尝试在Bjarne Stroustrup的C ++书中创建一个模仿代码示例的程序。这是制作计算器的初始方法,该计算器可以解析需要评估的较长表达式。 我还不关心运算符优先级,我正在尝试理解我当前代码所遇到的问题。这是:

#include <iostream>
using namespace std;

int main() {
  cout << "Expression: ";
  int lval = 0; //left-hand value
  int rval; // right-hand value
  char op;
  cin >> lval; //read leftmost operand
  while (cin>>op) { //read operator and righ-hand operand repeatedly
    cin >> rval;
    switch (op) {
    case '+':
      lval += rval; //add: lval = lval+rval
      break;
    case '-':
      lval -= rval; //subtract: lval = lval-rval
      break;
    case '*':
      lval *= rval; //multiply: lval =lval*rval
      break;
    case '/':
      lval /= rval; // divide: lval = lval/rval
      break;
    default:  // not another operator: print result
      cout << "Result: " << lval << '\n';
      return 0;
    }
  }
return 0;
}

当我编译并运行程序时,我总是需要添加两行额外的输入,例如:

$ ./calculator
>Expression: 1+2+3
>
>
[I can keep pressing enter as many times as I wish until I type in 2 more lines]
>l
>l
>Results: 6

为什么程序会以这种方式运行?为什么cin>>op在读取\n字符时不返回false?

这让我感到困惑,因为我从书中复制了while(cin>>op)部分。

2 个答案:

答案 0 :(得分:4)

对于while循环的每次迭代,您需要两个输入(cin >> opcin >> rval),这包括切换到default情况的最后一个输入。这就是你必须输入另外两行的原因。

答案 1 :(得分:2)

因为您正在为每次迭代读取cin>>opcin>>rval,并且此读取操作将阻塞,直到用户输入某个值。 >> operator不会读取换行符('\ n'),所以除非你输入其他值并按回车键,否则这两行都会阻塞,这就解释了为什么在写完表达式之后,无论你有多少次按Enter键将等待您输入另外两个值(第一个值开始非运算符值,以便执行默认的switch语句)以获得结果。

您可以使用cin.get()来获取运算符,因为它还会读取一个新行并在switch语句中为每个运算符读取rval以避免这种情况。

cout << "Expression: ";
  int lval = 0; //left-hand value
  int rval; // right-hand value
  char op;
  cin >> lval; //read leftmost operand
  while (cin.get(op)) { //read operator and righ-hand operand repeatedly
    switch (op) {
    case '+':
      cin >> rval;
      lval += rval; //add: lval = lval+rval
      break;
    case '-':
      cin >> rval;
      lval -= rval; //subtract: lval = lval-rval
      break;
    case '*':
      cin >> rval;
      lval *= rval; //multiply: lval =lval*rval
      break;
    case '/':
      cin >> rval;
      lval /= rval; // divide: lval = lval/rval
      break;
    default:  // not another operator: print result
      cout << "Result: " << lval << '\n';
      return 0;
    }
  }