3 integer calculator

Hey, I'm working on a three integer calculator to get used to if-then statements and to use a do while loop. I can get the calculator to work perfectly with two digits, then with additional code I've got the three integer to work. What I'm trying to accomplish is to put them together. I want to be able to type in either two integers or three integers and still get an answer. The problem is, whenever I type in a two integer problem it does nothing until I try to type in another problem, then it continually prints the first problem that it didn't solve. Here's my code:

#include <iostream>

using namespace std;

int main()
{
float x,y,z;
const int a = 6;
char funct, funct2;

cout<<" (X) (+) (Y) format (+)(-)(*)(/) :D :D :D\n\n";
do{
cin>>x>>funct>>y>>funct2>>z || cin>>x>>funct>>y;
cout<<"\n";


if (funct == '-' && funct2 == '-'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<x-y-z<<"\n\n";
}
else if (funct == '-' && funct2 == '+'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<x-y+z<<"\n\n";
}
else if (funct == '-' && funct2 == '*'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<x-(y*z)<<"\n\n";
}
else if (funct == '-' && funct2 == '/'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<x-(y/z)<<"\n\n";
}
else if (funct == '+' && funct2 == '-'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<x+y-z<<"\n\n";
}
else if (funct == '+' && funct2 == '+'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<x+y+z<<"\n\n";
}
else if (funct == '+' && funct2 == '*'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<x+(y*z)<<"\n\n";
}
else if (funct == '+' && funct2 == '/'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<x+(y/z)<<"\n\n";
}
else if (funct == '*' && funct2 == '-'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<(x*y)-z<<"\n\n";
}
else if (funct == '*' && funct2 == '+'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<(x*y)+z<<"\n\n";
}
else if (funct == '*' && funct2 == '*'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<x*y*z<<"\n\n";
}
else if (funct == '*' && funct2 == '/'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<(x*y)/z<<"\n\n";
}
else if (funct == '/' && funct2 == '-'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<(x/y)-z<<"\n\n";
}
else if (funct == '/' && funct2 == '+'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<(x/y)+z<<"\n\n";
}
else if (funct == '/' && funct2 == '*'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<x/y*z<<"\n\n";
}
else if (funct == '/' && funct2 == '/'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" "<<funct2<<" "<<z<<" = "<<x/y/z<<"\n\n";
}
else if(funct == '-'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" = "<< x-y<<"\n\n";
}
else if (funct == '+'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" = "<< x+y<<"\n\n";
}
else if (funct == '*'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" = "<< x*y<<"\n\n";
}
else if (funct == '/'){
cout<<"\t"<<x<<" "<<funct<<" "<<y<<" = "<< x/y<<"\n\n";
}
else {
cout<<"You're doing it wrong :P\n";
}
} while (a != '7');
return 0;
}



Any suggestions? Or is there a way that would have made this way easier?
Please use code tags when you post code. It makes it easier to read, as well as easier to reference mistakes.
cin>>x>>funct>>y>>funct2>>z || cin>>x>>funct>>y;

This makes no sense.

Or is there a way that would have made this way easier?


There is. The trick is to think about what a function is. Namely, an operation on two operands. You want to handle your input as pairs:

1
2
3
User Enters:  1 + 2 + 4
calculate 1 + 2  // which equals 3
calculate 3 + 4


So moslty, you need to think about how to manage the first operation "1 + 2", and each successive operation " + 4". Ultimately, you should be able to input a limitless amount of operations without having to change your code.

Ok I'm stuck. The original calculator script I had was:

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
#include <iostream>

using namespace std;



int main()
{
    float x,y;
    const int a = 6;
    char funct;
    cout<<"\t\t\t\tCalculate-ilizer!\n\t\t\t\t (+)(-)(*)(/) :D \n\t\t\t\t  PUt EM in\n";
    do{
        cin>>x>>funct>>y;
        if(funct == '+'){
            cout<<"\t"<<x<<" "<<funct<<" "<<y<<" = "<<x+y<<"\n";
        }
        else if (funct == '-'){
            cout<<"\t"<<x<<" "<<funct<<" "<<y<<" = "<<x-y<<"\n";
        }
        else if (funct == '*'){
            cout<<"\t"<<x<<" "<<funct<<" "<<y<<" = "<<x*y<<"\n";
        }
        else if (funct == '/'){
            cout<<"\t"<<x<<" "<<funct<<" "<<y<<" = "<<x/y<<"\n";
        }
        else{
            cout<<"\nYou done fucked up.\n Try again.";
        }
    } while(a != '7');
    return 0;
}



Same objective, just trying to make it able to accept three float problems without quadrupling the amount of if then statements. I've been looking at other scripts people had, but they don't work the same way I want to work mine. I want the user input to be the problem ex 1 * 4 + 3, and I don't want there to be a limit on how many numbers are involved. I dont want to make it a program where it baby steps you and asks what number do you want blah blah. I want it to be a working problem solver. This code works fine with that so far, just need to figure out how to extend the operations. Except I'm completely new to this whole thing really, just trying to learn with a goal(hands on learning).
I would recommend you use functions, a switch statement, and doubles instead of floats. So look those things up if you don't know how to use them.

Like I said, the operations you are doing require 2 operands and an operator. You then make a function doOperation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
double doOperation(double x, double y, char func)
{
  double result = 0;
  switch (func)
  {
  case '+': result = x + y;
  case '-': result = x - y; 
  case '*': result = x * y;
  case '/': if (y == 0)  cout << "Error: Can not divide by zero\n";
             else result = x / y;
  default:  cout << "Error:  Uknown Operator: " << func << '\n';
  }

  return result;
}


With that function, you can do this:
1
2
3
4
5
6
7
8
9
int main(void)
{
  double x = 20;
  double y = 2;
  char operator = '+';
  
  cout << x << " " << operator << y << " = " << doOperation(x,y,operator) << '\n';
  return 0;
}


So now you need to extract pairs of operands and an operator from the stream.

Here is a 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
56
57
58
59
60
61
// SwitchCalculator - use the switch state ment to implement a calculator

#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

int main(int nNumberofArgs, char* pszArgs[])
{
    // enter operand1 op operand2
    int nOperand1;
    int nOperand2;
    char cOperator;
    cout << "Enter 'value1 op value2'\n"
         << "where op is +, -, *, / or % (Enter = for op to quit):" << endl;
         for(;;)
         {
            cin >> nOperand1 >> cOperator >> nOperand2;

            // echo what the operator entered
            cout << nOperand1 << " "
                 << cOperator << " "
                 << nOperand2 << " = ";

                 // now calculatate the result; remember that the
                 // user might enter something unexpected
                 switch (cOperator)
                 {
                     case '+':
                        cout << nOperand1 + nOperand2;
                        break;
                     case '-':
                        cout << nOperand1 - nOperand2;
                        break;
                    case '*':
                    case 'x':
                    case 'X':
                        cout << nOperand1 * nOperand2;
                        break;
                    case '/':
                        cout << nOperand1 / nOperand2;
                        break;
                    case '%':
                        cout << nOperand1 % nOperand2;
                        break;
                    case '=':
                    system("PAUSE");
                    return 0;
                    break;
                    default:
                        // didn't understand the operator
                        cout << " is not understood";
                 }
                 cout << endl;

        }
    system("PAUSE");
    return 0;
}
I want the user input to be the problem ex 1 * 4 + 3, and I don't want there to be a limit on how many numbers are involved. I dont want to make it a program where it baby steps you and asks what number do you want blah blah. I want it to be a working problem solver.


Well, then you have a bigger problem.. Namely, you don't have the coding skills to do that yet. What if they type in 1 + 4 * 3? Your code will output 15 which is wrong since it ignores operator precedence. The correct answer would be 13. [the result of: 1 + (4 * 3)]. Remembering that multiplication has precedence over addition.

What you really need to do is PARSE the whole input strings into TOKENS. Then you need deal with operator precedence, input with parentheses, signed numbers, input errors, etc. This is a pretty big task but if you want to see it done right check out Stroustroup's Programming Principles and Practices. A tokenized OOP-based calculator is one of the first big projects in it.
Here is a huge program that I have failed to compress...

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// SwitchCalculator - use the switch state ment to implement a calculator

#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

void op1(int nOperand1, int nOperand2, char cOperator,int nOperand3,char cOperator2)
{
    int result;
    switch (cOperator)
    {
        case '+':
        result = nOperand1 + nOperand2;
        break;
        case '-':
        result = nOperand1 - nOperand2;
        break;
        case '*':
        case 'x':
        case 'X':
        result = nOperand1 * nOperand2;
        break;
        case '/':
        result = nOperand1 / nOperand2;
        break;
        case '%':
        result = nOperand1 % nOperand2;
        break;
        default:
        cout << " is not understood";
    }
    switch (cOperator2)
    {
        case '+':
        result = result + nOperand3;
        break;
        case '-':
        result = result - nOperand3;
        break;
        case '*':
        case 'x':
        case 'X':
        result = result * nOperand3;
        break;
        case '/':
        result = result / nOperand3;
        break;
        case '%':
        result = result % nOperand3;
        break;
        default:
        cout << " is not understood";
    }
    cout << result << endl;
}

void op2(int nOperand2, int nOperand3, char cOperator2,int nOperand1,char cOperator)
{
    int result;
    switch (cOperator2)
    {
        case '+':
        result = nOperand2 + nOperand3;
        break;
        case '-':
        result = nOperand2 - nOperand3;
        break;
        case '*':
        case 'x':
        case 'X':
        result = nOperand2 * nOperand3;
        break;
        case '/':
        result = nOperand2 / nOperand3;
        break;
        case '%':
        result = nOperand2 % nOperand3;
        break;
        default:
        cout << " is not understood";
    }
    switch (cOperator)
    {
        case '+':
        result = result + nOperand1;
        break;
        case '-':
        result = result - nOperand1;
        break;
        case '*':
        case 'x':
        case 'X':
        result = result * nOperand1;
        break;
        case '/':
        result = result / nOperand1;
        break;
        case '%':
        result = result % nOperand1;
        break;
        default:
        cout << " is not understood";
    }
    cout << result << endl;
}

int main(int nNumberofArgs, char* pszArgs[])
{
    int nOperand1;
    int nOperand2;
    int nOperand3;
    char cOperator;
    char cOperator2;
    cout << "Enter 'value1 op value2 op2 value3'\n"
         << "where op is +, -, *, / or %:" << endl;

    cin >> nOperand1 >> cOperator >> nOperand2 >> cOperator2 >> nOperand3;

    cout << nOperand1 << " "
    << cOperator << " "
    << nOperand2 << " "
    << cOperator2 << " "
    << nOperand3 << " = ";

    if(cOperator == '*' || cOperator == '/')
    {
        op1(nOperand1,nOperand2,cOperator,nOperand3,cOperator2);
    }
    else
    {
        op2(nOperand2,nOperand3,cOperator2,nOperand1,cOperator);
    }
    cout << endl;

    system("PAUSE");
    return 0;
}
This is a pretty big task but if you want to see it done right check out Stroustroup's Programming Principles and Practices. A tokenized OOP-based calculator is one of the first big projects in it.


Thanks, I'll check it out. And thanks greenleaf for the code example. I switched to switch last night and worked through that with my functions predefined. I'll be checking out everything I can to work on it myself. Sorry if it's a bad line of questioning, I was just working on it for awhile and still plan to keep going on with it. I wasn't sure what I needed to know to get it done. I'll be looking into the tokens and parsing in detail. :D You guys have been helpful, I really appreciate it.
The calculator gets complicated, but in small increments. I wouldn't worry about operator precedence until after doing parenthesis. Once parenthesis are done, all you need to do is insert parenthesis into the correct places and then do the looping. I wouldn't worry about parenthesis until you get something without parenthesis. Parenthesis make things a little more complicated, because at that point you will want to extract the whole entry as a string. Until then, you can deal with double and chars only.

An operation is two operands separated by an operand. This patter is always:

operand, operator, operand, operator, operand...
1 + 2 + 4 + 8

Therefor, you can start with two functions:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
double getOperand(void)
{
  // Without worring about strings/parenthesis, this is simple
  double result;
  std::cin >> result;
  return result;
}

double doOperation(double x, double y, char operation)
{
  double result = 0;
  switch(operation)
  {
  case '+': result = x + y; break;
  case '-': result = x - y; break;
  case '*': result = x * y; break;  
  case '/': if (y != 0) result = x / y;
        else std::cout << "Error: Divide By Zero\n";
        break;
  default:  std::cout << "Error: Invalid Function: " << operation << '\n';
  }  
  return result;
}


Remembering the pattern:
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
int main(void)
{
  double first, second;
  double result;
  char operation;
  
  first = getOperand();
  
  while (std::cin.peek() != '\n') // while there more in the buffer
  {
    std::cin >> operation;
    
    second = getOperand();
    
    result = doOperation(first, second, operation);
    
    // We can do a cout here if wanted
    std::cout<< first <<" " << operation << " " << second << " = " << result << '\n';
    
    // If there is more to do, we need to store result into first
    first = result;
  }
  // We are done
  std::cout << "The result is: " << result << '\n';
  return 0;
}


The next step is parenthesis. But, what is a parenthesis but an expression on it's own? We can move most of main into a function:

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
double getExpression(void)
{
  double first, second;
  double result;
  char operation;
  
  first = getOperand();
  
  while (std::cin.peek() != '\n')
  {
    std::cin >> operation;    
    second = getOperand();    
    result = doOperation(first, second, operation);    
    std::cout<< first <<" " << operation << " " << second << " = " << result << '\n';
    first = result;
  }
  return result;
}


int main(void)
{
  double result = getExpression();
  std::cout << "The result is: " << result << '\n';
  return 0;
}


Now that we are dealing with parenthesis, when we look for a number, it might be a '('. We also want to make sure that getExpression ends if the next character is a ')'. We also need to make sure that there are no blank spaces that might conflict.

Also, to make getNum() it's own function. Here is the whole thing:
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>

double getExpression(void);
double getOperand(void);
double getNum(void);
double doOperation(double x, double y, char operation);

int main(void)
{
  double result = getExpression();
  std::cout << "The result is: " << result << '\n';
  return 0;
}
double getExpression(void)
{
  double first, second;
  double result;
  char operation;
  
  first = getOperand();
  
  // Again, white space is trouble;
  while (std::cin.peek() == ' ') std::cin.ignore();
  
  // While not end of line AND not end of parenthesis
  while (std::cin.peek() != '\n' && std::cin.peek() != ')')
  {
    std::cin >> operation;    
    second = getOperand();    
    result = doOperation(first, second, operation);    
    std::cout<< first <<" " << operation << " " << second << " = " << result << '\n';
    first = result;
  }
  
  // We need to igore the ')'
  if (std::cin.peek() == ')') std::cin.ignore();  
  return result;
}

double getOperand(void)
{
  // Ignore white space
  while (std::cin.peek() == ' ') std::cin.ignore();
  
  // If this is a bracket
  if (std::cin.peek() == '(')
  {
  std::cin.get(); // remove it
  
  // Act as if this is a singular line
  return getExpression();  
  }
  else
  return getNum();
}

double getNum(void){
  double result = 0;
  if (!(std::cin >> result))
  {
    std::cin.clear();
    std::cin.ignore(80, '\n');
    std::cout << "Error: Non-Number entered\n";
  }
  return result;
}

double doOperation(double x, double y, char operation)
{
  double result = 0;
  switch(operation)
  {
  case '+': result = x + y; break;
  case '-': result = x - y; break;
  case '*': result = x * y; break;  
  case '/': if (y != 0) result = x / y;
        else std::cout << "Error: Divide By Zero\n";
        break;
  default:  std::cout << "Error: Invalid Function: " << operation << '\n';
  }  
  return result;
}
Last edited on
Can you explain to me all the cin. stuff? Don't know all of them...

Oh and can you use
 
using namespace std;


at the top of your program please? Makes life easier
Topic archived. No new replies allowed.