Reading input

In the previous lab we saw an example similar to this. Here we have input in the form of a string of text, containing three numbers. The sumThree method parses the string to find the three numbers, and adds each of them to the total.
package lab5;

import java.util.Scanner;

public class ScannerTest
{
  public static void main(String[] args)
  {
    int result = sumThree("42 237 5");
    System.out.println(result);
  }
  
  public static int sumThree(String text)
  {
    Scanner in = new Scanner(text);
    int total = 0;
    int num = in.nextInt();
    total = total + num;
    num = in.nextInt();
    total = total + num;
    num = in.nextInt();
    total = total + num;
    return total;
  }
}

How would we do this for a longer string of text with many numbers in it, such as
String text = "7 12 42 100 8 16 17 -9 55 2 2 2 1055 -99 0 3"
We would like to write a loop to compute the sum. But there is no general way to know in advance, given a string of text, how many numbers there are in it. (We can determine the number of characters in the string with the .length() method, but that tells us very little.)

What we need is something to implement the following pseudocode:

while there is another item in the input stream
    get the next item
    process it
The key is that the Scanner class has methods for looking ahead at the next item in the input stream - to see if there is one, and to check whether it can be parsed as a number. These methods do not actually read any input, but just return true or false without modifying the scanner or the input stream: The method for adding up the numbers in a text string then looks just like the pseudocode:
  public static int sumMany(String text)
  {
    Scanner in = new Scanner(text);
    int total = 0;
    while (in.hasNextInt())
    {
      int num = in.nextInt();
      total = total + num;     
    }
    return total;
  }

Reading from the console

The behavior of hasNext and the related methods is a bit surprising when reading from the console. The problem is obvious if you think about it: after you type something and hit Return, the runtime has no way of knowing whether you intend to type some more. When reading from a string, hasNext immediately returns true or false. When reading from the console, if you haven't typed ahead enough, it just waits for you to type some more. In order to ever conclude that hasNext is false, it needs to see a special sentinel value indicating the the end of input.

In most systems, the special value is a character produced by the key combination Ctrl-D (OS X or Linux) or Ctrl-Z (Windows). This mechanism is not entirely reliable when using the console pane within Eclipse, since Eclipse has its own ideas for special keystrokes. (You might try Cmd-D on a Mac.) Try out this version.

  public static int sumFromConsole()
  {
    Scanner in = new Scanner(System.in);
    int total = 0;
    while (in.hasNextInt())
    {
      System.out.print("Enter a number: ");
      int num = in.nextInt();
      total = total + num;     
    }
    return total;
  }