Reputation: 1000
I'm trying to make a program that mimics a code example in Bjarne Stroustrup's C++ book. This is an initial approach to make a calculator that can parse longer expressions that need to be evaluated. I don't care for operator precedence just yet, and I'm trying to understand an issue I'm having with my current code. Here it is:
#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;
}
When I compile and run the program, I always need to add two extra lines of input, for instance:
$ ./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
Why does the program behave this way? Why doesn't cin>>op
return false when a \n
character is read?
It confuses me because I copied the while(cin>>op)
part from the book.
Upvotes: 0
Views: 69
Reputation: 2233
Because you are reading cin>>op
and cin>>rval
for each iteration and this read operations will block until the user enters some value. The >> operator
will not read new line character('\n') so unless you enter some other value and press enter both of this lines will block,which explains why,after writing the expression, no matter how many time you press enter it will wait for you to enter two other values(the first value begin non-operator values so that the default switch statement is executed) to get to the result.
You could use cin.get()
to get the operator because it also reads a new line and read the rval within the switch statement for each operator to avoid this.
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;
}
}
Upvotes: 2
Reputation: 8215
For each iteration of the while loop, you need two inputs (cin >> op
and cin >> rval
), this includes the last one that switches to the default
case. That's why you have to enter the two additional lines.
Upvotes: 4