2

I have just went through a 70 video series on java. Time to take off training wheels so I am making a very simple program to take 2 text inputs for a class. It works the first making of a Car but throws an error on the second. I can not figure out why.

import java.util.Scanner;

class Car{

    public int cost;
    public double mpg;

    public void enterInfo() {
        Scanner reader = new Scanner(System.in);  // Reading from System.in
        System.out.println("Enter cost: ");
        this.cost = reader.nextInt(); // Scans the next token of the input as an int.
        System.out.println("Enter MPG: ");
        this.mpg = reader.nextDouble();
        reader.close();
    }




}

public class App {

    public static void main(String[] args) {

        Car car1 = new Car();
        car1.enterInfo();

        Car car2 = new Car();
        car2.enterInfo();

        System.out.println(car1.cost);
    }

}

Here's the 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.nextInt(Unknown Source)
    at java.util.Scanner.nextInt(Unknown Source)
    at uda01.Car.enterInfo(App.java:13)
    at uda01.App.main(App.java:32)
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • 3
    Use the one Scanner and `close` it at the very end – Reimeus Jun 24 '16 at 21:45
  • Ah makes sense now. – Tyler Rinker Jun 24 '16 at 21:46
  • Related: http://stackoverflow.com/questions/14962082/close-scanner-without-closing-system-in – Caramiriel Jun 24 '16 at 21:57
  • Trying to understand the down vote. Is it because I didn't follow a protocol set forth in the help center or because downvoting newbs makes you feel powerful and keeps those types from entering your world. If the former let me know what and I'll address it. If the later please read the help center guidelines yourself and seriously question why you'd frequent a help site if you intend to be inherently unhelpful. – Tyler Rinker Jun 25 '16 at 02:49

2 Answers2

1

The problem is that you are closing the scanner after reading the first Car object from it. When you do that, Scanner closes its underlying stream, i.e. System.in:

If this scanner has not yet been closed then if its underlying readable also implements the Closeable interface then the readable's close method will be invoked.

That is why the second read is unsuccessful.

One way to fix this problem is to make Scanner in your main, pass it to enterInfo, and close once the main is over:

public static void main(String[] args) {
    Car car1 = new Car();
    Car car2 = new Car();
    // Try with resource automatically closes your Scanner
    try(Scanner scanner = new Scanner(System.in)){
        car1.enterInfo(scanner);
        car2.enterInfo(scanner);
    }
    System.out.println(car1.cost);
    System.out.println(car2.cost);
}
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • 1
    @TylerRinker You are welcome! By the way, that's pretty good for a first program after a video course in a new programming language. One thing you may consider is combining `enterInfo` and `new Car()` in a single static method, so that you could call `Car car1 = enterInfo(scanner)` and `new Car()` would happen inside `enterInfo`. – Sergey Kalinichenko Jun 25 '16 at 02:57
1

I just wanted to say the same thing with dasblinkenlight. You shouldn't create scanner each time you call this method. More appropriate way is to send Scanner as a param. So, you could just update your code:

public class Car {
    public int cost;
    public double mpg;

    public void enterInfo(Scanner reader) {
        System.out.println("Enter cost: ");
        this.cost = reader.nextInt(); // Scans the next token of the input as an int.
        System.out.println("Enter MPG: ");
        this.mpg = reader.nextDouble();
    }
}


public class App {
    public static void main(String[] args) {
        try (Scanner reader = new Scanner(System.in)) {
            Car car1 = new Car();
            car1.enterInfo(reader);

            Car car2 = new Car();
            car2.enterInfo(reader);

            System.out.println(car1.cost);
        }
    }
}
Solorad
  • 904
  • 9
  • 21