infix to postfix converstion in C with multiple digits input

1.7k Views Asked by At

What I'm trying to obtain is a calculator that will take infix notation, ignore insignificant whitespace characters like " " or '@', then convert that infix notaion into postfix notation and do simple calculations like addition, subtraction etc. So far the code is taking input in infix notation trimming it in a way that ignores insignificant whitespace characters and outputs the postfix notation.

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>;
#include <ctype.h>;

#define MAX_LENGTH  100

//Functions
void push(char x);
char pop();
void trimString(char string[], char newString[]);
void inputToRPN(char trimmedExp[], char rpnExp[]);
int calculateRPN(char rpnExp[]);


char stack[MAX_LENGTH];
char resStack[MAX_LENGTH];
int top = -1;
int resTop = -1;
int index = 0;

int main() {
    int res;

    char exp[MAX_LENGTH] = "10 +2";
    char trimmedExpression[MAX_LENGTH];
    char rpnExpression[MAX_LENGTH];

    // Input commented out as per suggestion in comments
    //printf("Enter expression : ");
    //fgets(exp, 100, stdin);
    printf("Infix expression: %s \n", exp);
    trimString(exp, trimmedExpression);
    printf("\n");
    inputToRPN(trimmedExpression, rpnExpression);
    res = calculateRPN(rpnExpression);

    //printf("Result of calculation: %d", res);
    return 0;
}

void push(char x) {
    stack[++top] = x;
}

char pop() {
    if (top == -1)
        return -1;
    else
        return stack[top--];
}

int priority(char x) {
    if (x == '(')
        return 0;
    if (x == '+' || x == '-')
        return 1;
    if (x == '*' || x == '/')
        return 2;
    return 0;
}

void trimString(char string[], char newString[]) {
    int i = 0, j = 0;
    while (string[i] != '\0' && string[i] != 10) {
        // Range of significant characters
        if (string[i] >= '(' && string[i] <= '9') {
            newString[j] = string[i];
            i++, j++;
        }
        else {
            i++;
        }
    }
    newString[j] = 0;
}

void inputToRPN(char trimmedExp[], char rpnExp[]) {
    char* e, x;
    e = trimmedExp;

    while (*e != '\0') {
        // Add to RPN if character is alphanumeric
        if (isalnum(*e)) {
            rpnExp[index] = *e;
            index++;
        }
        // Add to stack if is an open brace
        else if (*e == '(')
            push(*e);
        // Add all operators to the expression until finding open braces
        else if (*e == ')') {
            while ((x = pop()) != '(') {
                rpnExp[index] = x;
                index++;
            }
        }
        // If none of the above, that is an operator - check it's priority.
        // If it's priority is less that that of the one on top of the stack add the operator from the top of the stack to the expression; untill it's priority is higher.
        // At the end add current operator to the stack.
        else {
            while (priority(stack[top]) >= priority(*e)) {
                rpnExp[index] = pop();
                index++;
            }
            push(*e);
        }
        e++;
    }

    while (top != -1) {
        rpnExp[index] = pop();
        index++;
    }

    // Terminating character at the end of the string
    rpnExp[index] = 0;
}

void pushRes(char x) {
    printf("pushing: %c \n", x);
    resStack[++resTop] = x;
}

char popRes() {
    printf("poping \n");
    if (resTop == -1)
        return -1;
    else
        return resStack[resTop--];
}

int isValidOperator(char c) {
    if (c == '/' || c == '*' || c == '+' || c == '-')
        return 1;
    else
        return 0;
}

int calculateRPN(char rpnExp[]) {
    // Doesnt do anything yet, just prints out the compiled reverse polish notation
    char* c;
    int result = 0;
    c = rpnExp;

    printf("Postfix expression: %s", rpnExp);

    return result;
}

The problem I've stumbled upon is when the infix input has multiple digits say 10+2 the code will treat each digit individually. Therefore the whole expression will be invalid when calculating result. I'm almost certain the issue lies in this line of code:

// Add to RPN if character is alphanumeric
if (isalnum(*e)) {
    rpnExp[index] = *e;
    index++;
}

Despite that I've got no idea how should i treat multiple digits while adding them to the expression, since the input is in form of character and there can be N amount of digits that have coresponding ascii values which range from 0-9. Looking forward to your answears.

Edit: made it so the code compiles and the input is hard coded.

1

There are 1 best solutions below

0
Kacper On

Okay, so thanks to Bodos suggestions I've fixed the issue. Adding one while loop in this section:

  if (isalnum(*e)) {
        rpnExp[index] = *e;
        index++;
    }

enabled me to add one character after every number (including the N digit ones). Thanks to which I was later able to perform calculations in calculateRPN function that would eventually lead to correct answear. The issue has been resolved.