Question

I'm having a lot of issues with my this code. I'm trying to make a program for homework that scans a text file and makes sure all brackets and parentheses (deliminator) match as pairs. I made a DelimPos class and built a constructor. This became my stack "s". Every time I encounter an opening delim in the file I push it onto the stack. When I encounter a closing delim I want to compare it to the top of the stack and pop the stack if the pair matches. When I pop the stack it returns a DelimPos type, but doesn't remove it from the stack.

Can you help me figure out what I'm doing wrong and provide any other criticisms you have. Just want to get a better.

    public class BalancedApp {

private static class DelimPos {

    private static int linecnt;
    private static char ch;

    public DelimPos(int lineCount, char character) { //constructor
        linecnt = lineCount;
        ch = character;
    }

    public static boolean match(char closeDelim) {
        if (getCharacter() == '(' && closeDelim == ')') return true;
        if (getCharacter() == '[' && closeDelim == ']') return true;
        if (getCharacter() == '{' && closeDelim == '}') return true;
        else return false;
    }

    public static char getCharacter() {
        return ch;
    }

    public static int getLineCount() {
        return linecnt;
    }
}

public static void main(String[] args) {
    //initialize stack
    Stack<DelimPos> s = new Stack<DelimPos>();

    int lineCount = 1;

    //get input for file
    System.out.printf("Enter file name: ");
    String fileName = new Scanner(System.in).nextLine();

    try{
        //check for file,open, and scan it
        Scanner inFile = new Scanner(new File(fileName));
        inFile.useDelimiter("");

        String text;
        System.out.print(lineCount + ". ");

        while(inFile.hasNext()){
            text = inFile.next();
            char character = text.charAt(0);

        //-------NEW LINE-------
            if(character == '\n') {
                //System.out.print(character);
                lineCount++;
                System.out.print("\n"+lineCount + ". ");
            }

        //-------CHECK FOR OPEN DELIM AND ADD TO STACK IF TRUE-------
            else if(character == '(' || character == '{' || character == '[') {
                System.out.print(character);
                s.push(new DelimPos(lineCount, character));
            }

        //-------CHECK FOR CLOSING DELIM, PRINT APPROPROATE ERROR, AND POP STACK
            else if(character == ')' || character == '}' || character == ']') {
                System.out.print(character);

                //---WHEN THERE IS AN EXTRA CLOSING DELIM---
                if (s.empty() == true) {
                    System.out.printf("\nError: Line %d. Closing character '%c', with no matching character.", lineCount, character);
                    System.exit(1);
                }

                boolean answer = DelimPos.match(character);

                //---WHEN CLOSING DELIM DOES NOT BALANCE WITH OPENING DELIM---
                if(answer == false) {
                    System.out.printf("\nError: Line %d. Symbol '%c' is the wrong closing symbol for char = '%c', line %d.", lineCount, character, DelimPos.getCharacter(), DelimPos.getLineCount());
                    System.exit(1);
                }
                else {
                    s.pop();  //<<<<<<<<<-----Where I'm having an issue
                    }
            }
            else {
                System.out.print(character);
            }
        }
        System.out.print("\nInput is balanced.");

        inFile.close();
    }
    catch (FileNotFoundException e) {
        System.out.printf("Unable to open file %s\n", fileName);
        System.exit(1);
    }
}

    import java.util.Stack;

----Editted code below, changed static objects into instance objects. @JeffWard explains below.----

public class BalancedApp {

private static class DelimPos {

    private int linecnt;
    private char ch;

    public DelimPos(int lineCount, char character) { //constructor
        linecnt = lineCount;
        ch = character;
    }

    public boolean match(char closeDelim) {
        if (this.getCharacter() == '(' && closeDelim == ')') return true;
        if (this.getCharacter() == '[' && closeDelim == ']') return true;
        if (this.getCharacter() == '{' && closeDelim == '}') return true;
        else return false;
    }

    public char getCharacter() {
        return ch;
    }

    public int getLineCount() {
        return linecnt;
    }
}

public static void main(String[] args) {

    int lineCount = 1;

    //get input for file
    System.out.printf("Enter file name: ");
    String fileName = new Scanner(System.in).nextLine();

    try{
        //initialize stack
        Stack<DelimPos> s = new Stack<DelimPos>();

        //check for file,open, and scan it
        Scanner inFile = new Scanner(new File(fileName));
        inFile.useDelimiter("");

        String text;
        System.out.print(lineCount + ". ");

        while(inFile.hasNext()){
            text = inFile.next();
            char character = text.charAt(0);

        //-------NEW LINE-------
            if(character == '\n') {
                lineCount++;
                System.out.print("\n"+lineCount + ". ");
            }

        //-------CHECK FOR OPEN DELIM AND ADD TO STACK IF TRUE-------
            else if(character == '(' || character == '{' || character == '[') {
                System.out.print(character);
                s.push(new DelimPos(lineCount, character));
            }

        //-------CHECK FOR CLOSING DELIM, PRINT APPROPROATE ERROR, AND POP STACK
            else if(character == ')' || character == '}' || character == ']') {
                System.out.print(character);

                //---WHEN THERE IS AN EXTRA CLOSING DELIM---
                if (s.empty() == true) {
                    System.out.printf("\nError: Line %d. Closing character '%c', with no matching character.", lineCount, character);
                    System.exit(1);
                }
            else {
                    DelimPos data = s.pop();
                    boolean answer = data.match(character);

                    //---WHEN CLOSING DELIM DOES NOT BALANCE WITH OPENING DELIM---
                    if(answer == false) {
                        System.out.printf("\nError: Line %d. Symbol '%c' is the wrong closing symbol for char = '%c', line %d.", lineCount, character, data.getCharacter(), data.getLineCount());
                        System.exit(1);
                    }
                }
            }
            else {
                System.out.print(character);
            }
        }
       if (s.empty() != true) {
           DelimPos data = s.pop();
            System.out.printf("\nError: At end of file, no closing symbol found for char = '%c', line %d.", data.getCharacter(), data.getLineCount());
            System.exit(1);
        }
        else {
            System.out.print("\nInput is balanced.");
            inFile.close();
        }
    }
    catch (FileNotFoundException e) {
        System.out.printf("Unable to open file %s\n", fileName);
        System.exit(1);
    }
}

}

Was it helpful?

Solution

The problem I see is that your DelimPos class is static including the member variables. Every delimiter that is encountered changes the value of ch in all items of the stack.

Considering the following input {{()}}

When the first ( is encountered the first two { would be changed. Add a toString() to your DelimPos like this:

@Override
public String toString() {
    return "Delim: " + ch;
}

If you run your program in a debugger and inspect you stack upon hitting the ( character you will see that your stack contains [Delim: (, Delim: (, Delim: (]

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top