简体   繁体   English

后缀中缀

[英]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. Xcode中的调试器说,它发生在评估文件中的中间文件的push和两个pop调用之间。 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. 每次不包含NULL指针作为其第一个参数的strtok()的调用都会将strtok()函数的内部指针重置为字符串的开头。

At the beginning of the loop in your int evaluate_postfix(char* postfix); 在您的int evaluate_postfix(char* postfix);循环开始时, 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). 但是您的堆栈很快就会耗尽,并且堆栈将开始指向垃圾数据(s-> size <0)。

token = strtok(postfix, " ");

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

Should fix your issue. 应该解决您的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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