1

I'm trying to get user input in a loop but it crashes on the second iteration of the while. I get input once but it crashes on the second time calling getInput(), I know for a fact that the first iteration is done fully.

while(!isAnagram(playerLetters,cw.toString())) {
        char userChar = getInput(); //crash on the second call
        System.out.println(userChar); //for debugging
        if(cw.toString().indexOf(userChar) == -1) 
            System.out.println("Character not in the word, try again");
        else {
            for(int i = 0; i < cw.numOfOccurrences(userChar); i++)//add the letter to correct guessed letter the number of time it occurs in the word 
                playerLetters = playerLetters + userChar;
            System.out.println("The character is in the word!");
        }
        System.out.println(userChar);   //for debugging
        printUI();
        trys++;
    }
    

And this is getInput():

private char getInput() {
    Scanner scan = new Scanner(System.in);
    String current = ""; 
    
    do {
        current = scan.next();
        if(current.length() > 1) 
            System.out.println("Please enter only one character");
        
        else if(usedLetters.contains(current.charAt(0))) 
            System.out.println("This character has already been used");
        
        else if(!Character.isLetter(current.charAt(0)) || !Character.isLowerCase(current.charAt(0)))  //Check if input is a lower case letter
            System.out.println("Invalid input");
        else {
            usedLetters.add(current.charAt(0));
            break;  
        }
    } while(true);
    
    scan.close();
    return current.charAt(0);

}
yftach
  • 31
  • 2
  • 1
    You're re-creating a new `Scanner` object for each invocation in `getInput` which is bad, because any kind of buffering or pre-reading that might happen inside the `Scanner` can mess up your result, you should only ever create one `Scanner` per input. I don't know enough about Scanner to know for sure that fixing this alone will fix your issue though. Generally speaking I'd discourage the use of `Scanner` for getting user input, as that API has a few ... peculiarities that make it ill-suited for that task. – Joachim Sauer Oct 23 '21 at 09:01
  • If you use `scan.close();` you are closing the underlying `System.in` which will cause and future `System.in` calls, or related scanners to fail. Either create a single scanner and use it for all inputs as suggested above, or simply don't close the scanner. – sorifiend Oct 23 '21 at 09:36
  • Managed to solve the isusse by passing the scanner as a parameter of the function and it solved the isuee but then I encountered it in other places so what I endded up doing is creating the scanner as a global object and passing it through the constructor to initialize it and it works perfectly now. Thank you guys! I wouldn't have managed to solve it without your comments! – yftach Oct 23 '21 at 09:50

1 Answers1

0

You can put

Scanner scan = new Scanner(System.in)

outside of getInput method to not call it each iteration in your class

Scanner scan = new Scanner(System.in);

private char getInput() {
   
    String current = ""; 
    
    do {
        current = scan.next();
        if(current.length() > 1) 
            System.out.println("Please enter only one character");
        
        else if(usedLetters.contains(current.charAt(0))) 
            System.out.println("This character has already been used");
        
        else if(!Character.isLetter(current.charAt(0)) || !Character.isLowerCase(current.charAt(0)))  //Check if input is a lower case letter
            System.out.println("Invalid input");
        else {
            usedLetters.add(current.charAt(0));
            break;  
        }
    } while(true);
    
   
    return current.charAt(0);

}

....
// then your loop 

while(!isAnagram(playerLetters,cw.toString())) {
        char userChar = getInput(); //crash on the second call
        System.out.println(userChar); //for debugging
        if(cw.toString().indexOf(userChar) == -1) 
            System.out.println("Character not in the word, try again");
        else {
            for(int i = 0; i < cw.numOfOccurrences(userChar); i++)//add the letter to correct guessed letter the number of time it occurs in the word 
                playerLetters = playerLetters + userChar;
            System.out.println("The character is in the word!");
        }
        System.out.println(userChar);   //for debugging
        printUI();
        trys++;
    }

// dont forget to close your scanner after the loop
 scan.close();
 
Lahcen
  • 1,231
  • 11
  • 15