- May 21, 2013
- 3,656
- 60
- 91
I've been mildly abusing you guys since this is my second question in as many weeks, but I do appreciate the help.
This is an assignment, I'm supposed to take a fully parenthesized infix equation and convert it to postfix and then calculate it.
So, input takes the form: (2 + 3) + 5 OR ((2 + 3) - (3 * 1)) + 4, etc.
I am hitting a segmentation fault as my make_postfix function ends, but I cannot identify what I'm doing wrong.
Relevant code attached:
Calculator.cpp
stack.hpp
The code has other problems, like throwing a bash error if I try to divide with '/', and leaving out the final operator if it's missing the outermost ( ). But all I really need assistance with is the segmentation fault.
It correctly converts to postfix. All the cout statements in the function show that much of it working.
Any help is appreciated. The code does compile cleanly using g++ -Wall, but like I said, segmentation fault.
This is an assignment, I'm supposed to take a fully parenthesized infix equation and convert it to postfix and then calculate it.
So, input takes the form: (2 + 3) + 5 OR ((2 + 3) - (3 * 1)) + 4, etc.
I am hitting a segmentation fault as my make_postfix function ends, but I cannot identify what I'm doing wrong.
Relevant code attached:
Calculator.cpp
Code:
#include <iostream>
//#include <cstring>
#include "stack.hpp"
//#include "utils.hpp"
void make_postfix(char in[]);
int main(void)
{
using namespace std;
char temp; // grabs characters as the user inputs them
int i, length; // loop counter, counts length of equation input
char express[50]; // holds the infix expression, without spaces
cout << "Enter an expression in infix notation: ";
do {
cin.get(temp);
if (temp != ' ' && temp != '\n') {
express[length] = temp;
length++;
}
} while(temp != '\n');
express[length] = '\0';
cout << "You typed: ";
for (i = 0; i < length; i++) {
cout << express[i];
}
cout << endl;
make_postfix(express);
cout << "Postfixed: ";
for (i = 0; i < length; i++) {
cout << express[i] << " ";
}
return 0;
}
void make_postfix(char in[])
{
using namespace std;
Stack<char> ops; // holds operators
char temp[50]; // holds interim postfix expression
char scrap; // receives the popped '('
int i = 0, j = 0; // loop counter and index marker, respectively
do {
cout << "Checking(j=" << j << "): " << in[j] << endl;
switch(in[j]) {
case ')':
do {
if (ops.top() != '(') {
temp[i] = ops.pop();
cout << "Popped: " << temp[i] << endl;
i++;
}
} while(ops.top() != '(');
if (ops.top() == '(') {
scrap = ops.pop();
cout << "Scrapped: " << scrap << endl;
}
break;
case '+':
case '-':
case '*':
case '/':
case '(':
ops.push(in[j]);
cout << "Pushed: " << ops.top() << endl;
break;
default:
temp[i] = in[j];
cout << "Added(i=" << i << ")(j=" << j << "): " << temp[i] << endl;
i++;
}
j++;
} while(in[j] != '\0');
do {
temp[i] = ops.pop();
i++;
} while(!ops.is_empty());
temp[i] = '\0';
cout << "Finished processing." << endl;
for (j = 0; j < i; j++) {
in[j] = temp[j];
cout << "Moved: " << in[j] << " at position " << j << "." << endl;
}
}
Code:
#ifndef _STACK_
#define _STACK_
// Type definitions
template <class Element>
struct list_element
{
Element value;
list_element<Element> *next;
};
template <class Element>
class Stack
{
public:
Stack();
~Stack();
Element top();
Element pop();
void push(Element e);
bool is_empty();
private:
list_element<Element> *m_first;
};
// Content that would normally go in the source file: Class implementation
// (Needs to be here because it is a template class.)
// constructor
template <class Element>
Stack<Element>::Stack()
{
m_first = NULL;
}
// destructor
template <class Element>
Stack<Element>::~Stack()
{
list_element<Element> *prev;
do {
prev = m_first;
m_first = m_first->next;
delete prev;
} while(m_first->next != NULL);
delete m_first;
}
// returns the top element of the stack, but doesn’t change the stack
template <class Element>
Element Stack<Element>::top()
{
return m_first->value;
}
// returns what was the top element of the stack, and also removes this element from the stack
template <class Element>
Element Stack<Element>::pop()
{
Element temp;
list_element<Element> *prev;
if (!is_empty()) {
temp = m_first->value;
prev = m_first;
m_first = prev->next;
delete prev;
}
return temp;
}
// adds element to top of stack
template <class Element>
void Stack<Element>::push(Element e)
{
list_element<Element> *n;
n = new list_element<Element>;
n->value = e;
if (is_empty()) {
m_first = n;
n->next = NULL;
}
else {
n->next = m_first;
m_first = n;
}
return;
}
// returns true if stack is empty, or false otherwise
template <class Element>
bool Stack<Element>::is_empty()
{
if (m_first) {
return false;
}
else {
return true;
}
}
#endif
It correctly converts to postfix. All the cout statements in the function show that much of it working.
Any help is appreciated. The code does compile cleanly using g++ -Wall, but like I said, segmentation fault.
Last edited: