0

I'm still learning how to code using java, and i run into problem that i can't solve myself.

compiler says :

Exception in thread "main" java.util.NoSuchElementException
    at java.util.Scanner.throwFor(Scanner.java:862)
    at java.util.Scanner.next(Scanner.java:1485)
    at java.util.Scanner.nextInt(Scanner.java:2117)
    at java.util.Scanner.nextInt(Scanner.java:2076)
    at GetInputData.main(GetInputData.java:10)

Here is the code

import java.util.Scanner;

public class GetInputData
{
  public static void main(String[] args)
  {
    Scanner in = new Scanner(System.in);
    int tag;
    System.out.println("Enter an integer: ");
    tag = in.nextInt();
    System.out.println("Input Integer is: "+tag);
  }
}

have been looking around for solution but it looks like lot of people had this kind of problem, so if any of you guys had other workaround can you please share to me, i just want a simple program that read from whatever we input, thanks.

Valagos
  • 9
  • 2
  • 3
    You must be doing something different - i ran your code verbatim and it worked perfectly. – corsiKa Mar 21 '18 at 16:06
  • 1
    @Andreas, wrong in this case it will fail with `java.util.InputMismatchException` – Sergey Prokofiev Mar 21 '18 at 16:08
  • From the [documentation](https://docs.oracle.com/javase/9/docs/api/java/util/Scanner.html#nextInt--): throws `NoSuchElementException` if input is **exhausted**. I don't know what you did, but you either terminated the input or the input was *empty*. There's something going on with the way you input the data. – Zabuzard Mar 21 '18 at 16:11
  • 1
    Note that there is `hasNextInt()` ([documentation](https://docs.oracle.com/javase/9/docs/api/java/util/Scanner.html#hasNextInt--)) which should be used prior to `nextInt()` to protect the access from this exception. – Zabuzard Mar 21 '18 at 16:11

2 Answers2

1

Here's the method throwFor from Scanner class in JDK that shows that it will throw NoSuchElementException if either (a) the input resource is closed or (b) you are entering an input that the buffer cannot hold.

From your code it looks like you are not closing the scanner (which you should at the very end). So the only possibility is that you are entering an invalid input.

By the way, this is not a compiler error, but a run time exception.

859     private void throwFor() {
860         skipped = false;
861         if ((sourceClosed) && (position == buf.limit()))
862             throw new NoSuchElementException();
863         else
864             throw new InputMismatchException();
865     }
VHS
  • 9,534
  • 3
  • 19
  • 43
  • 1
    *"which you should at the very end"* Except for a `Scanner` on `System.in`, since you shouldn't close `System.in`. The Java Runtime is responsible for opening and closing `System.in` (and `System.out` and `System.err`), so you shouldn't close them. – Andreas Mar 21 '18 at 16:27
  • @Andreas, I don't get why we shouldn't close a `Scanner` linked to `System.in`, if we are done reading data from the standard input. – VHS Mar 21 '18 at 16:57
  • It's about [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns) and the [single responsibility principle](https://en.wikipedia.org/wiki/Single_responsibility_principle). *Generally*, whoever allocates a resource is responsible for that resource, i.e. releasing it. You *can* deviate from that, if it is well-documented that the responsibility is transferred, which is most common in cases where a method returns a resource. In this case, the Java Runtime is responsible for the 3 system-owned streams, so you should not high-jack any of them and close the stream. – Andreas Mar 21 '18 at 18:15
  • Just because you *can*, doesn't mean you *should*. – Andreas Mar 21 '18 at 18:16
  • @Andreas, I agree with your statements. However, we create a `Scanner` resource (that implements `Closeable`). So it is our responsibility to close it. It is unfortunate that `System.in` is linked with the `Scanner` and closing the latter closes the former too. In my opinion, that needs to be addressed in the platform. – VHS Mar 21 '18 at 20:11
  • No, you don't create a `Scanner` *resource*. You create a `Scanner` resource when you use `new Scanner(File)` or `new Scanner(Path)`, but when you use `new Scanner(InputStream)` you create a *wrapper*. When wrapping an `InputStream`, the `Scanner` doesn't allocate any resources of it's own, so it doesn't need to be closed. – Andreas Mar 21 '18 at 20:16
0

I ran the code and it works as intended when working from the command line.

However, I tried creating an empty file, and piping that in, and I was able to reproduce the error.

So the problem lies in whatever your input mechanism is. Whether it's the wrong file or empty file or whatever, that's where you need to look to find the problem.

corsiKa
  • 81,495
  • 25
  • 153
  • 204