Passing a file into an Expression Tree

First the program will open a file which contains an infix expression that is fully parenthesized. The program will read this line and add it to an expression tree. It will then display the expression in prefix, postfix form and the result of the expression. The issue I am having is that I want the build_tree() in the main program to repeat itself for each line in the file. So if there were two expressions one on each line, it would display the different forms of expression and answer for each one. I have tried using the getline() function but the program crashes. The way I have it set up right now, it works good if there is just one line in the text file. Also it can only handle single digits as input. Any help would be appreciated.


Main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 #include <iostream>
#include "ET.h"
#include <string>
#include <fstream>
#include <algorithm>

using namespace std;

void build_tree(istream& in_f);


int main()
{
    ifstream infile;
    char file_name[100];
    string str;


     cout << "Enter a file name: ";
     cin >> file_name;               // Get file name

     infile.open(file_name);         // Open file
    if(!infile)                     // If we couldn't open the file...
    {
        cout << "Failed to open file." << endl;
        return 0;
    }

build_tree(infile);


infile.close();


    return 0;
}


void build_tree(istream& in_f){

ET e;
string expression;
    while(getline(in_f, expression)){

        e.build(in_f);
        cout << e;
        cout << "\nResult = " << e.computeValue();
    }


}



ET.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#ifndef ET_H
#define ET_H
#include <istream>
#include <fstream>
using namespace std;

class ET
{
   private:
       struct Node{

            char optr;
            int operand;
            Node *left;
            Node *right;

       };

       Node* root;

       //private function

       Node* help_build(istream& in_s);

       //printing
       void prefix(Node* r, std::ostream& out_s);
       void postfix(Node* r, std::ostream& out_s);
       void infix(Node* r, std::ostream& out_s);

       void destroy(Node* r);

       int eval(Node* x);


   public:

       ET();

       ~ET();

       void build(istream& in_s);


        int computeValue();

        friend std::ostream& operator << (std::ostream& out_s, ET& e);


};



#endif // ET_H 

ET.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "ET.h"
#include <istream>
#include <fstream>
using namespace std;
ET::ET(){
    root = NULL;
}

ET::~ET(){
    destroy(root);
}

void ET::destroy(Node *r){

  if(r != NULL)
    {
        destroy(r -> left);
        destroy(r -> right);
        delete r;
    }
}


void ET::build(istream& in_s){

    destroy(root); // make sure the tree is empty
    root = help_build(in_s);


}

ET::Node* ET::help_build(istream& in_s){

    char ch;
    Node* temp;
    in_s>>ch;
    if(isdigit(ch)){

        temp= new Node;
        temp -> operand = ch - '0';
        temp -> left = NULL;
        temp -> right = NULL;

    }else{

        temp = new Node;
        temp -> left = help_build(in_s);
        in_s>> temp -> optr;
        temp -> right = help_build(in_s);
        in_s >> ch; // ')'
    }
    return temp;
}

void ET::prefix(Node* r, ostream& out_s){

    if( r -> left == NULL){ // its a leaf
        out_s << r -> operand << " ";


    }else{
        out_s << r -> optr << " ";
        prefix(r -> left, out_s);
        prefix(r -> right, out_s);
    }
}

void ET::postfix(Node* r, ostream& out_s){

    if( r -> left == NULL){ // its a leaf
        out_s << r -> operand << " ";


    }else{

        postfix(r -> left, out_s);
        postfix(r -> right, out_s);
        out_s << r -> optr << " ";
    }
}

void ET::infix(Node* r, ostream& out_s){

 if( r -> left == NULL){ // its a leaf

        out_s << r -> operand << " ";


    }else{
        out_s << '(';
        infix(r -> left, out_s);
        out_s << r -> optr << " ";
        infix(r -> right, out_s);
        out_s << ')';
    }

}



ostream& operator << (ostream& out_s, ET& e){
    out_s << "Prefix: ";
    e.prefix(e.root, out_s);
    out_s << endl;
    out_s << "Infix: ";
    e.infix(e.root, out_s);

    out_s << endl;
    out_s << "Postfix: ";
    e.postfix(e.root, out_s);




    return out_s;
}

int ET:: eval(Node* x) {

    int result;

    switch (x -> optr) {
       case '+': result = eval(x->left) + eval(x->right);
               break;
       case '-': result = eval(x->left) - eval(x->right);
               break;
       case '*': result = eval(x->left) * eval(x->right);
               break;
       case '/': result = (eval(x->left)) / (eval(x->right));
               break;
       default:
            return x -> operand;

}
 return result;

}


int ET::computeValue(){
    return eval(root);
}

SOLVED:

changed the build_tree function in the main to this:
1
2
3
4
5
6
7
8
9
10
11
12
13
void build_tree(ifstream& in_f){

ET e;
string expression;

        e.build(in_f);
        cout << e;

        while(getline(in_f, expression)){
            e.build(in_f);
        cout << e;
        }
}
Topic archived. No new replies allowed.