Search code examples
javaterminalfilewriter

Scanner input gets appended to textfile despite condition in while-loop


I have a small little Java application that, on Terminal execution, will take string inputs, and saves those strings to a text file. I have the string exit that would prompt the application to exit. However, for some reason, the string exit gets appended to the document despite having that while(!) loop. What could be the issue?

try{
            Scanner scanner = new Scanner(System.in);
            String input = null;
            while(!"exit".equalsIgnoreCase(input)){
                input = scanner.nextLine();
                String fileLocation = "/Users/myName/Dropbox/myDocument.txt";
                FileWriter writer = new FileWriter(fileLocation,true);

                writer.append(returnDate()+": ");
                writer.append(input + "\n");

                writer.flush();
                writer.close();
            }
        }catch(Exception e){
            e.printStackTrace();
        }

Solution

  • Follow your code mentally. You do all the processing in the loop, before the while loop condition is evaluated the next time through.

    You have:

    while(!"exit".equalsIgnoreCase(input)){
        input = scanner.nextLine(); 
        ...
        writer.append(input + "\n");
        ...
    }
    

    Assuming the user types "exit" as the first command, the flow is:

    1. input is null initially.
    2. while condition succeeds.
    3. input is read, it is now "exit".
    4. input, i.e. "exit", is written to file.
    5. while loop restarts, condition is evaluated, fails, loop does not execute again.

    Note that "exit" was written to the file.

    You will have to rework your logic a bit to make sure that the file write does not occur. This is not an uncommon type of situation. There are many solutions depending on your preference. You could combine the assignment and comparison into the while statement:

    while (!"exit".equalsIgnoreCase(input = scanner.nextLine())) {
        write input;
    }
    

    You could have a redundant check (doesn't make sense for your simple example and also frequently indicates room for overall logic improvement):

    while (input is not exit) { 
        read input;
        if (input is not exit) write input;
    }
    

    You could not use the loop condition at all:

    while (true) {
        read input; 
        if (input is exit) break;
        write input;
    }
    

    There are many ways to fix it.