Home > Blockchain >  While loop is not working as expected. Everything seems to be correct. How do I fix this problem?
While loop is not working as expected. Everything seems to be correct. How do I fix this problem?

Time:05-02

So I have this program:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
       
        Scanner scan = new Scanner(System.in);
        String name = "";
        while(name.isBlank()) {
            System.out.println("Enter your name: ");
            name = scan.next();     
        }
        System.out.println("Hello "  name   "!");
    }
}

This program is supposed to prompt the user to enter their name. And it is supposed to keep prompting them until they actually enter their name meaning that if they keep the input field blank and press enter, they will get prompted again. However, this program does not do that. Even if I press ENTER without entering my name, the program just freezes and doesn't prompt again. Please help :(.

CodePudding user response:

You should use nextLine() rather than next() for the behavior you're trying to achieve.

As the documentation states:

A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.

next(): Finds and returns the next complete token from this scanner.

nextLine(): Advances this scanner past the current line and returns the input that was skipped.

The next() method interrupts its read once it encounters a white space, for example: a tab (\t), a line feed (\n), a carriage return (\r) or a proper space (there are also other characters which fall into the white space definition). When you keep typing a space or a new line at the beginning of your input while your Scanner is expecting something with a next() call, your Scanner instance will simply ignore it as "nothing" has been typed yet (nothing but a separator, which is not included in the returned value).

On the other hand, when you're invoking the nextLine() method, this one returns the current line, or the rest of the current line depending on where the internal Scanners cursor was left, excluding any line separator at the end. So, every time you're typing enter when a nextLine() is expecting an input, this will return an empty String as opposed to the next() method, which would block until some proper input and a separator have been entered.

Here is the tweaked version of your code:

public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    String name = "";
    while (name.isBlank()) {
        System.out.print("Enter your name: ");
        name = scan.nextLine();
    }
    System.out.println("Hello "   name   "!");
}

CodePudding user response:

I would like to supplement Dan's answer. The key here is what the documentation for next() indicates.

This method may block while waiting for input to scan

The question is, what does this mean? It means the OP's code works the way it is supposed to.

Enter your name: 
[ENTER pressed]
[ENTER pressed]
[ENTER pressed]
[ENTER pressed]
[ENTER pressed]
hector
Hello hector!

Because there was no input when ENTER was pressed, the call to next() method blocks waiting for input. Once input is entered, the scanner input is consumed and the proper output is produced. Because the method is blocking, no looping occurs; thus giving the appearance that the code is frozen when it is not.

CodePudding user response:

In your code you have used next() method to take the user input. Actually next() is used when you do not want the input string to be empty. So, if you are pressing enter before entering something non-empty, next() is expecting any non-empty string(waiting for the non-empty string) and neglecting all the whitespace characters entered before.

For your case you want to prompt after every enter if the name is empty. In this case you need to use nextLine() method instead, it will move to the next statement if the user presses enter. And then the condition inside while loop is checked.

Note: next() only accepts single word while nextLine() accepts multiple words.

The correct code is what @Dan has provided in his answer.

  •  Tags:  
  • java
  • Related