PPP2 Chapter 6 Section 6.3.1 Expression Calculator

In the PPP2 book, there's for an expression calculator that Stroustrup has us make through trial and error and he's using it to teach us program design and how think through a problem. He mentioned that each problem has a different set of requirements and that he won't go into that here, but that he'll try to arm us with enough knowledge to be able to solve a problem on our own (or at least, that's how I understood it).

Anyway, I have the code, but first I'll post about a use-case for it. Please compare it with the output from my code and help me figure out what I did wrong.

Here's the paragraph from the use-case.

This isn’t bad, but then we try 1+2*3 and see that the result is 9 and not the 7 our
arithmetic teachers told us was the right answer. Similarly, 1 – 2*3 gives – 3 rather
than the – 5 we expected. We are doing the operations in the wrong order: 1+2*3
is calculated as (1+2)*3 rather than as the conventional 1+(2*3) . Similarly, 1 – 2*3
is calculated as (1 – 2)*3 rather than as the conventional 1 – (2*3) . Bummer! We
might consider the convention that “multiplication binds tighter than addition” as
a silly old convention, but hundreds of years of convention will not disappear just
to simplify our programming.


And here's my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// expression_calc_1.cpp : Defines the entry point for the console application.
// Osman Zakir
// 1 / 3 / 2017
// Bjarne Stroustrup: Programming: Principles and Practice Using C++ 2nd Edition
// Chapter 6 Section 6.3.1 
// First attempt at expression calculator program

#include "../../std_lib_facilities.h"

int main()
{
	cout << "Please enter expression (we can handle +, -, *, and /)\n";
	cout << "add an x to end expression (e.g., 1+2*3x): ";
	int lval = 0;
	int rval;
	cin >> lval;
	cin.ignore();
	if (!cin)
	{
		error("no first operand");
	}
	for (char op; cin >> op;)
	{
		cin.ignore();
		if (op != 'x')
		{
			cin >> rval;
			cin.ignore();
		}
		if (!cin)
		{
			error("no second operand");
		}
		switch (op) 
		{
		case '+':
			lval += rval;
			break;
		case '–':
			lval -= rval;
			break;
		case '*':
			lval *= rval;
			break;
		case '/':
			lval /= rval;
			break;
		default:
			cout << "Result: " << lval << '\n';
			keep_window_open();
			return 0;
		}
	}
	error("bad expression");
}


Here's an example output:

Please enter expression (we can handle +, -, *, and /)
add an x to end expression (e.g., 1+2*3x): 1+2*3
Result: 1
Please enter a character to exit
k
Press any key to continue . . .


An output of 9 would also have been wrong, but at least it'd have been like the book said it should be. But here it's a completely different result.

Edit: From my debug attempt, it seems I should put a space there. But it doesn't seem like Stroustrup is putting in a space. So what's going on?

I noticed that when I do it without spaces, while lval has the right value, op ends up with the value of what should've been the second operand instead of the operation character.
Last edited on
Get rid of all those cin.ignore(); lines.
You get the 1 into lval then cin.ignore() discards the '+', then you take a 2 into op...and from there, everything get's messed up.
Do as cire says xD
Last edited on
Yeah, it works better that way. I put in those cin.ignore() calls because it clears out the input buffer, but I guess it's best for when there's an extra newline to clear out.
I put in those cin.ignore() calls because it clears out the input buffer, but I guess it's best for when there's an extra newline to clear out.

That strategy is for when you're mixing unformatted and formatted input extraction. You aren't doing so here.
Topic archived. No new replies allowed.