#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "stack.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)
{
char* postfix = malloc(MAX_EQU_LEN);
stack* s = create_stack();
s->size = strlen(infix);
node* tempPtr = s->stack;
unsigned int i;
char symbol,next;
for(i = 0; i < s->size ; i++)
{
symbol = *((infix + i));
tempPtr = s->stack;
if(isNumeric(&symbol) != 1)
{
strcat(postfix, &symbol);
}
else if(symbol == '(')
{
push(s, symbol);
}
else if(symbol == ')')
{
while(s->size != 0 && top(s) != '(')
{
next = tempPtr->data;
pop(s);
strcat(postfix, &next);
tempPtr = s->stack;
if(tempPtr->data == '(')
{
pop(s);
}
}
}
else
{
while(s->size != 0 && prec(top(s)) > prec(symbol))
{
next = tempPtr->data;
pop(s);
strcat(postfix, &next);
push(s,next);
}
}
while(s->size != 0)
{
next = tempPtr->data;
pop(s);
strcat(postfix, &next);
}
}
return postfix;
}
int evaluate_postfix(char* postfix) {
//For each token in the string
int i,result;
int right, left;
char ch;
stack* s = create_stack();
node* tempPtr = s->stack;
for(i=0;postfix[i] < strlen(postfix); i++){
//if the token is numeric
ch = postfix[i];
if(isNumeric(&ch)){
//convert it to an integer and push it onto the stack
atoi(&ch);
push(s, ch);
}
else
{
pop(&s[i]);
pop(&s[i+1]);
//apply the operation:
//result = left op right
switch(ch)
{
case '+': push(&s[i],right + left);
break;
case '-': push(&s[i],right - left);
break;
case '*': push(&s[i],right * left);
break;
case '/': push(&s[i],right / left);
break;
}
}
}
tempPtr = s->stack;
//return the result from the stack
return(tempPtr->data);
}
This file is part of a program that uses a stack struct to perform an infix to postfix on an input file. The other functions have been tested and work fine but when I try to add this part and actually perform the operations the program segmentation faults. A debugger says it occurs in the infix_to_postfix function however it doesn't say which line and I can't figure out where. Does anyone know why this would seg fault?
You've done a few things wrong:
if(isNumeric(&symbol) != 1)
The function isNumeric()
expects a null terminated string as input, not a pointer to a single character.
strcat(postfix, &symbol);
Here the same thing applies.
strcat(postfix, &next);
I'm guessing this is wrong too. If you want to turn a single character into a string, you can do this:
char temp[2] = {0};
temp[0] = symbol;
strcat(postfix, temp);
static int isNumeric(char* num)
{
if(atoi(num) == 0)
{
return 0;
}
return 1;
}
What if the string is "0"
? Consider using strtol
instead because it offers a more powerful means of testing the success of the outcome.
An unrelated stylistic note: your first function looks overcomplicated to me. Although it's perfectly possible that the way I'd do it is also overcomplicated.
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;
}
If a function performs a simple mapping from one set to another, It could usually be performed more simply (and faster) as an array lookup. So I'd start with a string of the input characters.
char *operators = "*" "/" "%" "+" "-";
Note that the compiler will concatenate these to a single string value with a null-terminator.
int precedence[] = { 5, 4, 3, 2, 1, 0 };
Then testing whether a char is an operator is:
#include <string.h>
if (strchr(operators, chr))
...;
And getting the precedence becomes:
p = precedence[strchr(operators, chr) - operators];
If there are more values to associate with the operator, I'd consider using an X-Macro to generate a table and a set of associated enum
values to use as symbolic indices.
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.