我正在尝试创建一个程序来将中缀表达式转换为后期修复并使用堆栈进行评估。这三个文件如下。当我运行代码时,我得到了一个分段错误。 Xcode中的调试器表示它发生在evaluate_postfix函数中的push和两个pop调用之间。任何人都可以帮我解释为什么这是断层错误?
#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;
}
答案 0 :(得分:0)
每次调用不包含NULL指针作为其第一个参数的strtok()都会将strtok()函数的内部指针重置为字符串的开头。
在int evaluate_postfix(char* postfix);
功能的循环开始时,您可以调用
token = strtok(postfix, " ");
这意味着在循环开始时,令牌ALWAYS指向后缀开头的第一个非空格字符。因此每个循环都会看到一个运算符,并尝试从堆栈中弹出()两个值。但是你的堆栈很快就会耗尽,堆栈将开始指向垃圾数据(s-> size&lt; 0)。
token = strtok(postfix, " ");
for(i = 0; i < s->size ; i++)
{
....
token = strtok(NULL, " ");
}
应该解决你的问题。