19

I am expecting input with the scanner until there is nothing (i.e. when user enters a blank line). How do I achieve this?

I tried:

while (scanner.hasNext()) {
    // process input
}

But that will get me stuck in the loop

tshepang
  • 10,772
  • 21
  • 84
  • 127
Jiew Meng
  • 74,635
  • 166
  • 442
  • 756

5 Answers5

21

Here's a way:

Scanner keyboard = new Scanner(System.in);
String line = null;
while(!(line = keyboard.nextLine()).isEmpty()) {
  String[] values = line.split("\\s+");
  System.out.print("entered: " + Arrays.toString(values) + "\n");
}
System.out.print("Bye!");
Bart Kiers
  • 153,868
  • 34
  • 276
  • 272
  • 3
    This has a side effect of getting the line already (eg. I'd need to split the line by spaces for example if I want to parse values separated by spaces). Is there a `hasNextLine()` type method where the "pointer" doesn't goto the next line? – Jiew Meng Sep 06 '11 at 13:24
  • 1
    @jiewmeng - when you call `scanner.hasNext()` you will need to still fetch the line to check whether it is empty and process it. Could you explain why Bart's answer would not work for you? – luketorjussen Sep 06 '11 at 13:44
  • The problem with splitting the line is that it defeats the purpose of the `Scanner`, which is that it helps you do the tokenizing. – 200_success Nov 21 '17 at 22:23
7

From http://www.java-made-easy.com/java-scanner-help.html:

Q: What happens if I scan a blank line with Java's Scanner?

A: It depends. If you're using nextLine(), a blank line will be read in as an empty String. This means that if you were to store the blank line in a String variable, the variable would hold "". It will NOT store " " or however many spaces were placed. If you're using next(), then it will not read blank lines at all. They are completely skipped.

My guess is that nextLine() will still trigger on a blank line, since technically the Scanner will have the empty String "". So, you could check if s.nextLine().equals("")

AlexFZ
  • 1,399
  • 1
  • 11
  • 22
4

The problem with the suggestions to use scanner.nextLine() is that it actually returns the next line as a String. That means that any text that is there gets consumed. If you are interested in scanning the contents of that line… well, too bad! You would have to parse the contents of the returned String yourself.

A better way would be to use

while (scanner.findInLine("(?=\\S)") != null) {
    // Process the line here…
    …

    // After processing this line, advance to the next line (unless at EOF)
    if (scanner.hasNextLine()) {
        scanner.nextLine();
    } else {
        break;
    }
}

Since (?=\S) is a zero-width lookahead assertion, it will never consume any input. If it finds any non-whitespace text in the current line, it will execute the loop body.

You could omit the else break; if you are certain that the loop body will have consumed all non-whitespace text in that line already.

200_success
  • 6,669
  • 1
  • 36
  • 68
0
Scanner key = new Scanner(new File("data.txt"));
String data = "";

while(key.hasNextLine()){
    String nextLine = key.nextLine();

    data += nextLine.equals("") ? "\n" :nextLine;

}
System.out.println(data);
demongolem
  • 8,796
  • 36
  • 82
  • 101
rush2sk8
  • 325
  • 5
  • 15
-1

AlexFZ is right, scanner.hasNext() will always be true and loop doesn't end, because there is always string input even though it is empty "".

I had a same problem and i solved it like this:

do{
    // process input
}while(line.length()!=0);
I think do-while will fit here better becasue you have to evaluate input after user has entered it.
hukko
  • 117
  • 2