简体   繁体   中英

Infix to Postfix

I am trying to create a program to convert an infix expression to post fix and evaluate it using a stack. The three files are below. When I run the code I get a segmentation fault. The debugger in Xcode says that it occurs between the push and the two pop calls in the middle file in the evaluate_postfix function. Can anyone help me with why this is seg faulting?

#include <stdio.h>
#include <stdlib.h>
#include "stack.h"


stack* create_stack(void)
{
    stack* newPtr = malloc(sizeof(stack));
    newPtr->size = 0;
    newPtr->stack = NULL;

    return newPtr;
}


void push(stack *s, int val)
{
    node* newPtr = (node*) malloc(sizeof(node));
    newPtr->data = val;
    newPtr->next = s->stack;
    s->stack = newPtr;
    s->size++;
}

void pop(stack *s)
{
    node* newPtr = NULL;
    node* tempPtr = NULL;

    tempPtr = s->stack;
    newPtr = tempPtr->next;
    free(tempPtr);
    s->stack = newPtr;
    s->size--;

}


int top(stack *s)
{
    int num;
    node* newPtr = NULL;
    newPtr = s->stack;
    num = newPtr->data;

    return num;
}

int isEmpty(stack *s)
{
    if(s->stack == NULL)
    {
        return 1;
    }

    else
    {
        return 0;
    }
}

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "stack.h"
#include <string.h>

#define MAX_EQU_LEN 100

static int prec(char operator)
{
    switch (operator)
    {
        case '*':
            return 5;
        case '/':
            return 4;
        case '%':
            return 3;
        case '+':
            return 2;
        case '-':
            return 1;
        default:
            break;
    }

    return 0;
}

static int isNumeric(char* num)
{
    if(atoi(num) == 0)
    {
        return 0;
    }
    return 1;
}

char* infix_to_postfix(char* infix)
{
    int i,a=0;
    char* postfix = malloc(MAX_EQU_LEN);
    stack* s = create_stack();

    for(i=0;infix[i]!='\0';i++){

        if(!isNumeric(&((infix[i]))))
        {
            postfix[a]=infix[i];
            a++;
        }
        else if(isEmpty(s))
            push(s,infix[i]);
        else if(prec(infix[i])>prec(s->stack->data))
                push(s,infix[i]);
        else
            {
                postfix[a]=s->stack->data;
                a++;
                pop(s);
                if(!isEmpty(s)){
                    while(prec(s->stack->data)<= prec (infix[i]))
                    {
                        postfix[a]=s->stack->data;
                        a++;
                        pop(s);
                    }
                }
                else
                    push(s,infix[i]);
            }
        }
    return postfix;

}


int evaluate_postfix(char* postfix) {

    int i,result = 0;
    int right = 0, left = 0;
    char* token = NULL;
    stack* s = create_stack();
    s->size = strlen(postfix);
    node* tempPtr = NULL;
    for(i = 0; i < s->size ; i++)
    {

        token = strtok(postfix, " ");
        if(isNumeric(token) == 1)
        {

            atoi(token);
            push(s, *token);
        }
        else
        {
            left = tempPtr->data;
            pop(s);
            right = tempPtr->data;
            pop(s);
            switch(*token)
            {
                case '+':
                    result = left + right;
                    break;
                case '-':
                    result = left - right;
                    break;
                case '*':
                    result = left * right;
                    break;
                case '/':
                    result = left / right;
                    break;
                case '%':
                    result = left % right;
                    break;

            }
            push(s, result);
        }
        strtok(NULL, " ");
    }
    return result;

}       
#include <stdio.h>
#include <string.h>
#include "calculator.h"

#define BUFFERSIZE 100

int main(int argc, char* argv[]) {

    char buffer[BUFFERSIZE];
    if (argc != 2) {
        printf("correct ussage: %s <input file>\n", argv[0]);
        return 1;
    }

    FILE* fp = fopen(argv[0], "r");

    if(fp == NULL) {
        printf("unable to open file: %s\n", argv[1]);
        return 1;
    }

    while(fgets(buffer, BUFFERSIZE, fp)) {
        if (buffer[strlen(buffer)-1] == '\n') {
            buffer[strlen(buffer)-1] = '\0';
        }
        char *postfix = infix_to_postfix(buffer);
        int result = evaluate_postfix(postfix);
        printf("%s = %d\n", buffer, result);
    }

    return 0;
}

Each call to strtok() that doesn't contain a NULL pointer as its first argument resets the internal pointer of the strtok() function to the beginning of the string.

At the beginning of the loop in your int evaluate_postfix(char* postfix); function, you call

token = strtok(postfix, " ");

Which means that at the beginning of the loop, token ALWAYS pointers to the first non-space character at the beginning of postfix. So each loop it would see an operator, and try to pop() two values from the stack. But your stack would quickly deplete, and the stack will begin to point to garbage data (s->size < 0).

token = strtok(postfix, " ");

for(i = 0; i < s->size ; i++)
  {
  ....
  token = strtok(NULL, " ");
 }

Should fix your issue.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM