0

I'm working on a program that allows the user to specify one of three functions via keyboard input. Each of the functions works properly except for one. When it exits back to the initial prompt it outputs the prompt to the console twice.

Here's the opening prompt: "Type 'R/r' to read a file; 'S/s' to search for text within a file; 'W/w' to write to a file; 'E/e' to exit"

When I run any of the listed functions (barring exit) they execute normally and return to the opening prompt. The search function however prints the opening prompt twice to the console instead of once.

This is the code for the Opening:

public static void main(String args[]) throws IOException{

    //Initialize scanner and a string variable to hold the value of scanner variable
    Scanner inputChoice = new Scanner(System.in);       //iChoice - inputChoice


    while(!inputChoice.equals("e")){
        //Prompt user to provide input in accordance with desired function
        System.out.println("Type 'R/r' to read a file; 'S/s' to search for text within a file; 'W/w' to write to a file; 'E/e' to exit");

        String userChoice = inputChoice.nextLine();

        //If user specifies "r" go to fileReader class
        if(userChoice.equalsIgnoreCase("r")){
            SimpleDBReader sdbrObject = new SimpleDBReader();
            sdbrObject.sdbReader();

            //If user specifies "s" go to textSearch class
        }else if(userChoice.equalsIgnoreCase("s")){
            SimpleDBSearch sdbsObject = new SimpleDBSearch();
            sdbsObject.sdbSearch(inputChoice);

            //If user specifies "w" go to fileWriter class
        }else if(userChoice.equalsIgnoreCase("w")){
            SimpleDBWriter sdbwObject = new SimpleDBWriter();
            sdbwObject.sdbWriter(inputChoice);

            //If user specifies "e" terminate program
        }else if(userChoice.equalsIgnoreCase("e")){
            inputChoice.close();
            System.exit(0);
        }
    }
}

This is the code for the Search:

public void sdbSearch(Scanner searchWord) throws IOException{

    //Prompt user for input
    System.out.println("Please input the word you wish to find:");

    //Init string var containing user input
    String wordInput = searchWord.next();

    //Specify file to search & init Scanner containing file
    File file = new File("C:/Users/Joshua/Desktop/jOutFiles/SimpleDb.txt");
    Scanner fileScanner = new Scanner(file);

    //Set flag - for below loop - to false
    boolean stringFound = false;

    //Loops through every line looking for lines containing previously specified string.
    while(fileScanner.hasNextLine()){
        String line = fileScanner.nextLine();
        if(line.contains(wordInput)){       //If desired string is found set flag true and print line containing it to console
            stringFound = true;
            System.out.println("I found the word you're looking for here: " + line);
        }
    }

    //Check if flag false, prompt user for new input
    if(!stringFound){
        System.out.println("The word you were looking for does not exist.");
    }
}

The interaction and output I expect is:

Type 'R/r' to read a file; 'S/s' to search for text within a file; 'W/w' to write to a file; 'E/e' to exit  //SysOut
s   //User
Please input the word you wish to find:     //SysOut
someString  //User
I found the word you're looking for here: lineWithString    OR   The word you were looking for does not exist.      //SysOut
Type 'R/r' to read a file; 'S/s' to search for text within a file; 'W/w' to write to a file; 'E/e' to exit  //SysOut

What I get is:

Type 'R/r' to read a file; 'S/s' to search for text within a file; 'W/w' to write to a file; 'E/e' to exit  //SysOut
s   //User
Please input the word you wish to find:     //SysOut
someString  //User
I found the word you're looking for here: lineWithString    OR   The word you were looking for does not exist.      //SysOut
Type 'R/r' to read a file; 'S/s' to search for text within a file; 'W/w' to write to a file; 'E/e' to exit  //SysOut
Type 'R/r' to read a file; 'S/s' to search for text within a file; 'W/w' to write to a file; 'E/e' to exit  //SysOut            
  • You can easily answer this kind of question for yourself by stepping through in a debugger. – Eric J. Nov 11 '15 at 17:52
  • 1
    When reading the word, try using `nextLine()` instead of `next()`. In particular, this line `String wordInput = searchWord.next();` – Clark Nov 11 '15 at 17:55
  • 1
    You've got an error in the while loop in your `main`-Method as well. You are comparing the Scanner for equality with the String "e" which will never be true: `!inputChoice.equals("e")` – Hendrik Simon Nov 11 '15 at 18:05
  • @HendrikSimon I use that so that Main doesn't terminate after one iteration of any function. inputChoice will only ever be equivalent to 'e' when the suer specifies so. – Joshua Napier Nov 11 '15 at 18:10
  • @Joshua No, `inputChoice` will never be equivalent to `'e'`. It is a `Scanner`, not a `String`. You probably meant to refer to `userChoice`, but that variable hasn't been declared yet at that point. – David Conrad Nov 11 '15 at 18:13
  • You also shouldn't be closing `inputChoice` since it's a wrapper around `System.in` and you didn't open it. The rule is, close anything you open, but only things you open, although in practice this is harmless. – David Conrad Nov 11 '15 at 18:14
  • `fileScanner`, on the other hand, which wraps a file you opened, you should close, but never do. – David Conrad Nov 11 '15 at 18:15
  • @DavidConrad How would I go about fixing it then? By switching the condition with 'true'? I was closing inputChoice because Java didn't like me leaving the Scanner open in a previous version of this code. – Joshua Napier Nov 11 '15 at 18:22
  • @DavidConrad I haven't closed fileScanner yet because my search function is still in progress. I intend on closing it when I finish it. – Joshua Napier Nov 11 '15 at 18:23
  • You could move the declaration of `userChoice` outside the loop and assign it some default value, or change the condition to `true`. There are probably a lot of ways to rewrite it. – David Conrad Nov 11 '15 at 18:31

1 Answers1

2

Call to scanner.next() leaves behind a newline character which is then read in call to scanner.nextLine(). Add a scanner.nextLine() after searchWord.next(); or better change searchWord.next(); to searchWord.nextLine();

TheLostMind
  • 34,842
  • 11
  • 64
  • 97
  • So ".next()" provides the equivalent of a carriage return allowing for the prompt to be read as the next line? – Joshua Napier Nov 11 '15 at 18:13
  • 1
    `.next()` leaves behind the linefeed at the end of the line the user typed when they entered the term to search for, so it's still in the buffer when the main program goes to read the next `userChoice`. – David Conrad Nov 11 '15 at 18:17
  • @JoshuaNapier - Yes. `next()` leaves behind a newline character which will be read by `nextLine()`. Please go through the question used to mark this question as dup.(dang, should have done it before answering :P) – TheLostMind Nov 11 '15 at 18:23