# VBForums CodeBank > CodeBank - C++ >  Simple rpn calculator

## BenJones

Hi, this is a simple reverse polish notation calulator in C it takes the input as postfix and and shows the result. this is very basic code I not added any functions but I may do in time. One rule of the code is that all numbers and operators must be seperated by a space. Anyway hope you find it intresting if you like more information on RPN you can check out https://en.wikipedia.org/wiki/Reverse_Polish_notation



```
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

#define MAX_EXPR 1024
#define MAX_TOKEN 30
#define MAX_STACK 100
#define TRUE 1
#define FALSE 0

//Points to top of stack.
int st =-1;
//Stack holds the values.
float STACK[MAX_STACK] = {0.0};

int is_num(char *src){
    //Function to test if we have a number works for decimal places
    int x = 0;
    int ok = TRUE;

    while(x < strlen(src)){
        //Test for digit or dot
        if(!isdigit(src[x]) && src[x] != '.'){
            ok = FALSE;
            break;
        }
        x++;
    }
    return ok;
}

int is_op(char op){
    if(op == '+' || op == '-' ||
       op == '*' || op == '/'){
        return TRUE;
       }
       return FALSE;
}

void Push(float v){
    STACK[++st] = v;
}

float Pop(){
    return STACK[st--];
}

float calc_rpn(char *expr){
    char zToken[MAX_TOKEN];
    char src[MAX_EXPR];
    float a = {0.0};
    float b = {0.0};
    int x = 0;
    int y = 0;

    st = -1;
    //Make a copy of expr
    strcpy(src,expr);

    //Append last space so the string will split properly and not miss the end of the string.
    strcat(src," ");

    while(x < strlen(src)){
        //Check for space
        if(src[x] == ' '){
            //Zap end of string.
            zToken[y] = '\0';
            //Check for number.
            if(is_num(zToken) == TRUE){
                //Push the number onto the stack
                Push(atof(zToken));
            }else{
                //Process operators
                switch(zToken[0]){
                case '+':
                    a = Pop();
                    b = Pop();
                    Push(b+a);
                    break;
                case '-':
                    a = Pop();
                    b = Pop();
                    Push(b-a);
                    break;
                case '*':
                    a = Pop();
                    b = Pop();
                    Push(b*a);
                    break;
                case '/':
                    a = Pop();
                    b = Pop();
                    Push(b/a);
                    break;
                }
            }
            //Reset y
            y = 0;
        }else{
            //Build string buffer.
            zToken[y] = src[x];
            //INC string buffer index
            y++;
        }
        x++;
    }
    //Clear up
    memset(zToken,0,sizeof zToken);
    memset(src,0,sizeof src);
    //Pop off result.
    return Pop();
}


int main()
{
    //5 + 5 / (5 * 3) + 120 - (4+8)
    float c = calc_rpn("5 5 5 3 * / + 120 + 4 8 + -");
    //Print result
    printf("%f\n",c);

    //Clear stack
    memset(STACK,0,sizeof STACK);

    return 0;
}
```

----------


## BenJones

Here is a new update of my RPN calulator a lot of chnages now supports Functions and Variables hope you like the update.



```
// RPN Calculator with mathematical functions and variables
// By Ben a.k.a DreamVB
// Feel free to use modify this code as you wish.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>

#define MAX_EXPR 2048
#define MAX_TOKEN 30
#define MAX_STACK 256
#define MAX_VARS 50
#define TRUE 1
#define FALSE 0

//Points to top of stack.
int st = -1;
//Stack holds the values.
double STACK[MAX_STACK] = {0.0};

enum tok_types{
    DIGIT = 1,
    OP = 2,
    STR = 3,
    EOP = 4
};

int pos = 0;
int tok_type = 0;
char Token[MAX_TOKEN] = {0.0};
char Expr[MAX_EXPR] = {'\0'};

struct t_variable {
    char vName;
    double value;
};

int var_count = 0;
struct t_variable variables[MAX_VARS];

int is_op(char op);
void GetToken();

void add_var(char vn, double value){
    //Add a new variable name
    variables[var_count].vName = vn;
    //Add variable value
    variables[var_count].value = value;
    //INC variable counter
    var_count++;
}

void UCase(char *s){
    //Just upper-case a string.
    while(*s){
        *s = toupper(*s);
        s++;
    }
}

int var_index(char *v){
int x  = 0;
int idx = -1;
    //This checks of v is in variables[n]
    while(x < var_count){
        //Check for variable name
        if(v[0] == variables[x].vName){
            //Store the found index
            idx = x;
            break;
        }
        x++;
    }
    //Return index
    return idx;
}

void GetToken(){
    //RPN calulator lexer
    int t = 0;
    tok_type = 0;

    //Check if at end of expression
    if(pos >= strlen(Expr)){
        //Set token type to EOP
        tok_type = EOP;
    }
    //Skip over white spaces
    while(isspace(Expr[pos])){
        //INC counter
        pos++;
    }
    //Check for digit or dots
    if(isdigit(Expr[pos]) || Expr[pos] == '.'){
        //Grab all the digits
        while(isdigit(Expr[pos]) || Expr[pos] == '.'){
            //Build token
            Token[t] = Expr[pos];
            t++;
            pos++;
        }
        //Zap end of token
        Token[t] = '\0';
        //Set token type to digit
        tok_type = DIGIT;
    //Check for operators
    }if(is_op(Expr[pos])){
        while(is_op(Expr[pos])){
            //Build token
            Token[t] = Expr[pos];
            pos++;
            t++;
        }
        //Set token type to operator
        tok_type = OP;
        //Zap end of token
        Token[t] = '\0';
    //Check for alpha
    }else if(isalpha(Expr[pos])){
        while(isalpha(Expr[pos])){
            //Build token
            Token[t] = Expr[pos];
            t++;
            pos++;
        }
        //Zap end of token
        Token[t] = '\0';
        //Set token type to string
        tok_type = STR;
    }
}

int is_op(char op){
    //Tests for an operator
    if(op == '+' || op == '-' ||
       op == '*' || op == '/' ||
       op == '%'){
        return TRUE;
       }
       return FALSE;
}

void Push(double v){
    //Push value on stack
    STACK[++st] = v;
}

double Pop(){
    //Pop value from top of stack
    return STACK[st--];
}

double q(double f){
    //Return square root
    return f*f;
}

int is_math_func(char *f){
    //Upper-case token
    UCase(Token);
    //Check if we have a function name and return true if found.
    if(strcmp(f,"SIN") == 0){
        return TRUE;
    }
    if(strcmp(f,"COS") == 0){
        return TRUE;
    }
    if(strcmp(f,"LOG") == 0){
        return TRUE;
    }
    if(strcmp(f,"EXP") == 0){
        return TRUE;
    }
    if(strcmp(f,"SQR") == 0){
        return TRUE;
    }
    if(strcmp(f,"POW") == 0){
        return TRUE;
    }
    //No function so retune false
    return FALSE;
}

void mathfunc(char *f){
    double a = 0.0;

    //Pop of item from stack
    a = Pop();

    //Upper-case token
    UCase(Token);
    //Process inbuilt functions
    if(strcmp(f,"SIN") == 0){
        Push(sin(a));
    }
    if(strcmp(f,"COS") == 0){
        Push(cos(a));
    }
    if(strcmp(f,"LOG") == 0){
        Push(log(a));
    }
    if(strcmp(f,"EXP") == 0){
        Push(exp(a));
    }
    if(strcmp(f,"SQR") == 0){
        Push(q(a));
    }
    if(strcmp(f,"POW") == 0){
        Push(pow(Pop(),a));
    }
}

double calc_rpn(char *n){
    //RPN parser
    double a = 0;
    double b = 0;
    int vId = 0;

    //Make a copy of the expression
    strcpy(Expr,n);
    //Get first token
    GetToken();

    //While not EOP get and process the tokens
    while(tok_type != EOP){

        //Check for digit tokens
        if(tok_type == DIGIT){
            //Push value on top of the stack
            Push(atof(Token));
        }
        //Check for string token
        if(tok_type == STR){
            //Test if we have a inbuilt math function
            if(is_math_func(Token) == TRUE){
                //Process maths function
                mathfunc(Token);
            }
            else{
                //Must be a variable
                //Get variable index
                vId = var_index(Token);
                //Check if variable was found
                if(vId != -1){
                    //Push the value of the variable on the stack.
                    Push(variables[vId].value);
                }
            }
        }
        //Process operatos
        if(tok_type == OP){
            switch(Token[0]){
                case '+':
                    //Pop of the top two items on the stack
                    a = Pop();
                    b = Pop();
                    //Push the result back onto the stack
                    Push(b+a);
                    break;
                case '-':
                    //Pop of the top two items on the stack
                    a = Pop();
                    b = Pop();
                    //Push the result back onto the stack
                    Push(b-a);
                    break;
                case '*':
                    //Pop of the top two items on the stack
                    a = Pop();
                    b = Pop();
                    //Push the result back onto the stack
                    Push(b*a);
                    break;
                case '%':
                    //Pop of the top two items on the stack
                    a = Pop();
                    b = Pop();
                    if(a != 0.0){
                        //Push the result back onto the stack
                        Push(fmod(b,a));
                    }else{
                        printf("Division By Zero.\n");
                    }
                    break;
                case '/':
                    //Pop of the top two items on the stack
                    a = Pop();
                    b = Pop();

                    if(a != 0.0){
                        //Push the result back onto the stack
                        Push(b/a);
                    }
                    else{
                        printf("Division By Zero.\n");
                    }
                    break;
            }
        }
        //Get next token.
        GetToken();
    }
    //Pop of the result from the stack.
    return Pop();
}

int main()
{
    //Add variables
    add_var('A',120);
    add_var('B',5);

    //Expression to calulate
    double c = calc_rpn("B 5 5 3 * / + A + 4 8 + -");
    //Print result
    printf("%lf\n",c);
    //Clear stack
    memset(STACK,0,sizeof STACK);

    return 0;
}
```

----------


## Sherin

Please try this code, Too Simple RPN, calculator.



```
if(calcStack.size() > 2 )                      
{
    cout << "Error: too many operands" << endl;
    return 1;
}
else if(isOperator(input))
{
    performOperation(input, calcStack);
}
else if(input == "=")
{
    if (calcStack.size() != 1)
    {
        cout << "Error: too many operands" << endl;
        return 1;
    }
    else
    {
        cout << "Result: " << calcStack.top();
        calcStack.pop(); 
    }
}
```



```
switch (input[0])
{
    case '-':
        result = firstOperand - secondOperand;
        break;
    case '+':
        result = firstOperand + secondOperand;
        break;
    case '*':
        result = firstOperand * secondOperand;
        break;
    case '/':
        if (secondOperand == 0)
        { // moved this test to here because it's the only place it matters.
            cout << "Error: Division by 0.\n";
            return -1;
        }
        result = firstOperand / secondOperand;
        break;
}
```

I hope this code will be useful to you.
Thank you.

----------


## 2kaud

Seems to be in-complete - one nested if statement and one switch statement ??? :Confused:

----------

