-1

I made a postfix calculator and I'm pretty sure it works however it as a reading error. The calculator is designed to read numbers in postfix notation from a line in a file and calc them. However it doesn't recognize lines, for example if I have two lines it will combine the two expressions. I have trouble with file reading so any help would be appreciated. Sorry for any format problem this is my first post. So here is my code so my issue is better understood.

import java.io.*;
import java.util.*;
import java.nio.charset.Charset;


public class PostfixCalculator {

private static final String ADD = "+"; 
private static final String SUB = "-";
private static final String MUL = "*";
private static final String DIV = "/";
private static final String EXP = "^"; 
private static final String NEG = "_";  //unary negation
private static final String SQRT = "#";

public void calculateFile(String fileName) throws IOException {
    BufferedReader br = null;
    StringBuilder sb = null;
    try {
        FileReader fileReader = new FileReader(fileName);
        br = new BufferedReader(fileReader);

        sb = new StringBuilder();
        String line = br.readLine();

        while (line  != null) {
            sb.append(line);
            line = br.readLine();
        }

        String input = sb.toString();
        System.out.println(input + " = " + calculate(input));
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        br.close();
    }


   } 

private double calculate(String input) {
    SinglyLinkedListStack<Double> stack = new SinglyLinkedListStack<Double>();

    String[] inputs = input.split(" ");

    return handleCalculation(stack, inputs);
}

private static double handleCalculation(SinglyLinkedListStack<Double> stack, String[] el) {
    double operand1, operand2;

    for(int i = 0; i < el.length; i++) {
        if( el[i].equals(ADD) || el[i].equals(SUB) || el[i].equals(MUL) || el[i].equals(DIV)||el[i].equals(EXP)||el[i].equals(NEG)||el[i].equals(SQRT)) {
            operand2 = stack.pop();
            operand1 = stack.pop();
            switch(el[i]) {
                case ADD: {
                    double local = operand1 + operand2;
                    stack.push(local);
                    break;
                }

                case SUB: {
                    double local = operand1 - operand2;
                    stack.push(local);
                    break;
                }

                case MUL: {
                    double local = operand1 * operand2;
                    stack.push(local);
                    break;
                }

                case DIV: {
                    double local = operand1 / operand2;
                    stack.push(local);
                    break;
                }
                case EXP: {
                    double local = Math.pow(operand1, operand2);
                    stack.push(local);
                    break; 

                }
                case NEG: {
                    double local = -(operand1);
                    stack.push(local);
                    break;
                }
                case SQRT:{ 
                    double local = Math.pow(operand1, .5);
                    stack.push(local);
                    break; 
                }

            }
        } else {
            stack.push(Double.parseDouble(el[i]));
        }
    }

    return (double)stack.pop();
}

}

This is my linked list

public class SinglyLinkedListStack<T> {

private int size;
private Node<T> head;

public SinglyLinkedListStack() {
    head = null;
    size = 0;
}

public void push(double local) {
    if(head == null) {
        head = new Node(local);
    } else {
        Node<T> newNode = new Node(local);
        newNode.next = head;
        head = newNode;
    }

    size++;
}

public T pop() {
    if(head == null)
        return null;
    else {
        T topData = head.data;

        head = head.next;
        size--;

        return topData;
    }
}

public T top() {
    if(head != null)
        return head.data;
    else
        return null;
}

public int size() {
    return size;
}

public boolean isEmpty() {
    return size == 0;
}

private class Node<T> {
    private T data;
    private Node<T> next;

    public Node(T data) {
        this.data = data;
    }

}


}

This is my demo

import java.io.IOException;

public class PostFixCalculatorDemo {
 public static void main(String[] args) throws IOException {
    PostfixCalculator calc = new PostfixCalculator();
    calc.calculateFile("in.dat");
}
}

The text file contains

2 3 ^ 35 5 / -

1 2 + 3 * # 4 - 5 6 - + _

my output is 2 3 ^ 35 5 / -1 2 + 3 * # 4 - 5 6 - + _ = -8.0 as it is seen it is combining the two lines. I want it to read the two lines separately and calculate 2 3 ^ 35 5 / - and 1 2 + 3 * # 4 - 5 6 - + _ without putting it together. I know it does this because I programmed the calculateFile class wrong but I am not sure how to fix this without breaking my program.

masalaman
  • 1
  • 2
  • 1
    Where's the error? – shmosel Aug 31 '17 at 20:16
  • The error is that it cannot read the file line by line – masalaman Aug 31 '17 at 20:19
  • That's just a vague problem description. If there's an error, you should have an error message and a stack trace. Post it here. – shmosel Aug 31 '17 at 20:20
  • Possible duplicate of [Read String line by line in Java](https://stackoverflow.com/questions/1096621/read-string-line-by-line-in-java) –  Aug 31 '17 at 20:20
  • If mean there's a *bug* in your code, you'll need to describe it more clearly. Post your input, output, expected output etc. – shmosel Aug 31 '17 at 20:21

1 Answers1

0
 while (line  != null) {
        sb.append(line);
        line = br.readLine();
    }

Basically you are reading every line and appending it to a single Stringbuffer which will result in concatenation of every line from your file. This buffer wont contain newline character or any other sign where your lines end.

From the documentation:

readline:

Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.

Returns: A String containing the contents of the line, not including any line-termination characters, or null if the end of the stream has been reached Throws:

I advice adding the lines to an ArrayList if you are planning to read everything at once.

Ervin Szilagyi
  • 2,393
  • 2
  • 10
  • 20