Calculator with order of operations

Hey so I wrote a calculator program where you can write an expression and the program solves it.

For a long time I've wondered how to make a program like this, that parses an expression and then solves it step by step according to the order of operations.

So here's my attempt at cracking this problem. I'm still a beginner so feel free to suggest improvements.

Just a heads up: The calculator handles addition, subtraction, multiplication, division, powers and roots. The expression can be as long as need be.
It doesn't support parenthesis nor decimal points.

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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include <iostream>
#include <string>
#include <vector>
#include <deque>

#include <math.h>

using namespace std;

class token 
{
    public:
        double num1,num2;
        char op;

        token(double a, char b, double c) : num1(a),op(b),num2(c){};
        token() : num1(0),op(0),num2(0){};
        void initialize(double a, char b, double c) {num1 = a; op = b; num2 = c; return;}
        double solve()
        {
            switch(op)
            {
                case '+' : return (num1+num2);
                case '-' : return (num1-num2);
                case '*' : return (num1*num2);
                case '/' : return (num1/num2);
                case '^' : return (pow(num1,num2));
                case 'r' : return (pow(num2,1/num1));
            }
        }
};


string expression;
deque<double> numbers;
deque<char> operators;


void express()
{
    cout << "'+' to add\n'-' to subtract\n'*' to multiply\n'/' to divide\n'^' for powers\n'r' for roots\n\n";
    cout << "Enter your expression:\n";
    cin >> expression;
    return;
}

void extract() //Turns an expression into a list of numbers and operators.
{
    vector<int> digits;
    unsigned int i,k; int temp=0;

    for (i=0; i<=expression.size(); i++)
    {
        if (expression[i]>='0' && expression[i] <='9') digits.push_back(expression[i]-'0');
        else {
                operators.push_back(expression[i]);
                for (k=0; k<digits.size(); k++) temp+=digits.at(k)*pow(10,(digits.size()-1-k));
                numbers.push_back(temp);
                digits.clear();
                temp=0;
             }
    }
    operators.erase(operators.end());
    return;
}


void addsub() //Does adding and subtracting.
{
        token tempp;
        double temp = numbers.at(0);

    while (true)
    {
        if (operators.at(0) == '+' || operators.at(0) == '-')
        {
                numbers.erase(numbers.begin());
                tempp.initialize(temp ,operators.at(0), numbers.at(0));
                temp = tempp.solve();

                if (operators.size() == 1)
                {
                    operators.clear();
                    numbers.at(0) = temp;
                    return;
                }

                else
                operators.erase(operators.begin());
        }
    }
}



void multidiv() //Does multiplication and division.
{
        token tempp;
        double temp;
        unsigned int i;

    for (i=0; i<operators.size(); i++)
    {
        if (operators.at(i) == '*' || operators.at(i) == '/')
        {
            tempp.initialize(numbers.at(i) ,operators.at(i), numbers.at(i+1));
            temp = tempp.solve();

            if (operators.size() == 1)
                {
                    operators.clear();
                    numbers.at(0) = temp;
                    return;
                }

                else
                {
                    operators.erase(operators.begin()+i);
                    numbers.erase(numbers.begin()+i+1);
                    numbers.at(i) = temp;
                }
            --i;
        }
    }
    addsub();
}


void calculate() //Does powers and roots.
{
        token tempp;
        double temp;
        unsigned int i;

    for (i=0; i<operators.size(); i++)
    {
        if (operators.at(i) == '^' || operators.at(i) == 'r')
        {
            tempp.initialize(numbers.at(i) ,operators.at(i), numbers.at(i+1));
            temp = tempp.solve();

            if (operators.size() == 1)
                {
                    operators.clear();
                    numbers.at(0) = temp;
                    return;
                }

                else
                {
                    operators.erase(operators.begin()+i);
                    numbers.erase(numbers.begin()+i+1);
                    numbers.at(i) = temp;
                }
            --i;
        }
    }
    multidiv();
}



int main ()
{
    express();
    extract();
    calculate();

    cout << "Final answer: " << numbers.at(0) << endl << endl;

    return 0;
}
It is a very good attempt. Well done!

Now, try to extend the program:
a. allow spaces in the input: eg. '23 + 7 * 35'
b. allow parenthesis: eg. '(23+7)*35'
c. add error handling: eg. '23++7*35' : error: invalid token '+' (at position 3)
so I wrote a calculator program

You may take a CAS like

https://reduce-algebra.sourceforge.io
or
http://maxima.sourceforge.net

as a role model.
And if you have some spare time to spend you may merge best of several to a "Super-CAS".
https://en.wikipedia.org/wiki/List_of_computer_algebra_systems

In case you like to play with emulators: http://www.hp-prime.de/en/category/15-software
(BTW, read the advertisement carefully, if you are no student it is not the best graphing CAS calculator.)
Topic archived. No new replies allowed.