David
David

Reputation: 11

How to use Scanner in both main and method

I'm trying to get input in both my main and other methods, but I'm not clear on how to get the scanner working in both.

It gives me a weird error:

Exception in thread "main"
java.util.NoSuchElementException
 at java.util.Scanner.throwFor(Unknown Source)
 at java.util.Scanner.next(Unknown Source)
 at java.util.Scanner.nextDouble(Unknown Source)
 at Hwk11.getRainData(Hwk11.java: 28)
 at Hwk11.main(Hwk11.java: 18)

Code:

import java.util.Scanner;
public class Hwk11 {
  public static void main(String[] args) {
    Scanner stdin = new Scanner(System.in);
    System.out.println("How many weeks of data do you have?");
    int numWeeks = stdin.nextInt();
    if (numWeeks <= 0 || numWeeks > 52) {
      System.out.println("Invalid number of weeks.");
    }
    else {
      double[] rainWeeks = new double [numWeeks];
      getRainData(rainWeeks);
      showRain(rainWeeks);
    }
  }

  public static void getRainData(double[] rainFall) {
    Scanner stdin = new Scanner(System.in);
    System.out.println("Enter the weekly rainfall for each week.");
    for (int index = 0; index < rainFall.length; index++) {
      System.out.println("Week number " + (index + 1) + ":");
      rainFall[index] = stdin.nextDouble();
    }
  }

  public static void showRain(double[] rainFall) {
    for (int index = 0; index < rainFall.length; index++) {
      System.out.print(rainFall[index] + " ");
    }
  }
}

Upvotes: 1

Views: 2476

Answers (2)

Stephen C
Stephen C

Reputation: 718836

People are saying "works for me".

The problem that the behavior (whether it works or not) depends on exactly how input is provided.

  • If you provide input interactively, it will probably work.
  • If you provide input by redirecting standard input like this:

      java Hwk11 < input.txt
    

    then it won't.

The problem is that a Scanner will read-ahead and buffer any characters available from its input stream. That is fine normally, but in your code you have created two distinct Scanner objects to read from System.in. Thus when standard input is redirected:

  • The first Scanner.nextInt call will cause most / all of the input to be buffered in the first Scanner
  • When the second Scanner is created and Scanner.nextDouble is called, it won't see the input buffered in the first Scanner and that will lead to an exception ... when it runs out of input characters "too soon".

The solution is to NOT create multiple Scanner objects for the same input stream. Use one Scanner and either put it in a field, or pass it as a parameter to all of the places that it needs to be used.

Upvotes: 2

alikhtag
alikhtag

Reputation: 326

Works for me. Don't enter anything but a double if you asking for next double so no "2.3 cm", just pass 2.3 and add cm when you print in

I am assuming your showRain(double[] rainFall) method probably executes before getRaindata(double[] rainFall) is able to finish and populate the array. Array you passsing to showRain(double[] rainFall) might be empty.

Try putting your method call for showRain(double[] rainFall) after loop in getRanData(double[] rainFall)

Alternitivly try passing the whole Scanner object to method.

public static void getRainData(double[] rainFall, Scanner stdin) {
  //Scanner stdin = new Scanner(System.in);
  System.out.println("Enter the weekly rainfall for each week.");
  for (int index = 0; index < rainFall.length; index++) {
    System.out.println("Week number " + (index + 1) + ":");
    rainFall[index] = stdin.nextDouble();
  }
  showRain(rainFall); 
}

Don't forget to close it when you done with scanner.

Upvotes: -1

Related Questions