-1

I'm doing some homework where we have to use the Scanner class. I was able to use it to read in a String, an int, and a float. When I moved to the next phase (the class below) I suddenly am not able to use scanner the way I had before. I did indeed close any other scanner object I created and opened. Thank you for any help.

Why does this code: (nextLine() also does not work)

import java.io.*;
import java.util.Scanner;

public class Grades {
private int len;
private String [] gradeNames;
private int [] gradeArray;
private int enterGradeNames(){
    Scanner input = null;
    input = new Scanner(System.in);
    for (int i = 0; i < len; ++i){
        System.out.println("Enter the type of grades you will be reporting: (" + 
                (i + 1) + " of " + gradeArray.length + ")" );
        gradeNames[i] = new String(input.next() );
    }
    input.close();
    return 0;
}
protected int displayGradeNames(){
    System.out.println("Type of Grades tracking");
    for (int i = 0; i < len; ++i)
        System.out.println(gradeNames[i]);
    return 0;
};
public Grades(){
    len = 0;
    Scanner input = null;
    input = new Scanner(System.in);
    System.out.println("Enter the size of the grade array to be created");
    len = 4;
    gradeArray = new int[len];
    gradeNames = new String[len];
    input.close();
    enterGradeNames();
}

}

give me this errror:

Enter the type of grades you will be reporting: (1 of 4)

Exception in thread "main" java.util.NoSuchElementException

at java.util.Scanner.throwFor(Unknown Source)

at java.util.Scanner.next(Unknown Source)

at Grades.enterGradeNames(Grades.java:14)

at Grades.(Grades.java:34)

at Demo1.main(Demo1.java:32)

** Oh.. i should mention that it doesn't even give the option to input data before throwing the error

Community
  • 1
  • 1
gjnave
  • 479
  • 4
  • 14
  • Your using ++i. Change to i++ – Ele Nov 22 '13 at 22:22
  • 2
    @EleazarEnrique, that is definitely not the problem. The prefix increment operator is perfectly valid – Floegipoky Nov 22 '13 at 22:30
  • so, i added a hasNext() coniditonal - which keeps the code from crashing - however does not solve the problem of why the app is not prompting for input... "null, null, null, null" – gjnave Nov 22 '13 at 23:07
  • @Floegipoky you're right, I saw something wrong with ++i cuz it's increasing before eval the index. Anyway, it's missing the hasNext() method. – Ele Nov 22 '13 at 23:19

3 Answers3

2

The problem is in your enterGradeNames() method with:

input.next()

You have to first call input.hasNext();

From documentation:

Throws: NoSuchElementException - if no more tokens are available.

EDIT: as per comments

I am unable to reproduce the problem, but there are many unnecessary lines in your code, so try running this edited code and see whether it changes anything.

public class Grades {
private int len;
private String [] gradeNames;
private int [] gradeArray;

private int enterGradeNames(){
    Scanner input = new Scanner(System.in);
    for (int i = 0; i < len; i++){
        System.out.println("Enter the type of grades you will be reporting: (" + 
                (i + 1) + " of " + gradeArray.length + ")" );
        gradeNames[i] = new String(input.next());
    }
    return 0;
}

public Grades(int length){
    this.len = length;
    gradeArray = new int[len];
    gradeNames = new String[len];
}

It's not generally good choice to call non-static methods inside constructor as the object isn't finished yet. You could do this in a (factory) method instead:

public static Grades buildGrades(){
    Scanner s = new Scanner(System.in);
    System.out.println("Enter size:");
    int size = s.nextInt();
    Grades grades = new Grades(size);
    grades.enterGradeNames();

    return grades;
}

EDIT2:

I searched a bit and the problem might be with your closing of the Scanner. Because if you call close on the Scanner, it will look whether its stream implements Closeable and if so it will close it as well. I never thought System.in would be closeable, but it is.

So the best option? Possibly use one Scanner for the whole program OR just don't close it if you dont want its stream to be closed. More can be read here.

Community
  • 1
  • 1
Kuba Spatny
  • 26,618
  • 9
  • 40
  • 63
  • yeah, comments to "go check the documentation" are usually not useful as you can't assume someone hasn't. Whats more helpful is assistance in interpreting the meaning of the documentation. I still don't understand why checking "hasNext" which seemingly returns a bool is going to make my scanner suddenly work. – gjnave Nov 22 '13 at 22:56
  • @gjnave it's not going to make it work. I though the documentation makes it clear enough.. hasNext tells you whether there is some token (string, int, ..) which can be returned. But if hasNext() returns false, it means there is no token, hence you shouldn't be calling the next() method, if you will then it must throw an Exception, because there is no element. – Kuba Spatny Nov 22 '13 at 23:10
  • ok so heres the crux of the problem -besides that our teacher has explained none of this - (thank you for your reply), there is no token to return --- all that I understand about the class is that you call the "next..." method to input and the user inputs something. So, what do you do if there is no token to return? (i have googled this to no joy btw) – gjnave Nov 22 '13 at 23:17
  • 1
    @gjnave I am really unable to run the program at the moment, but I made some changes to your code, so check edited answer. And what to do when there are no data, well it really depends on you, but you could f.e. stop the program and say "Error: no user input." – Kuba Spatny Nov 22 '13 at 23:48
  • good edited post. thx. SO... the problem is still happening BUT I've isolated it to a previous class "Person" which uses a Scanner and then closes it. If I dont call that class then the above code works. If i do call it then it breaks. any ideas? – gjnave Nov 23 '13 at 01:32
  • @gjnave See edited answer. Try not to close your Scanner, hopefully it will resolve the problem. – Kuba Spatny Nov 23 '13 at 10:34
0

try it with this:

public Grades(){
len = 0;
Scanner input = null;
input = new Scanner(System.in);
System.out.println("Enter the size of the grade array to be created");
len = 4;
gradeArray = new int[len];
gradeNames = new String[len];
enterGradeNames();
input.close();
}
Yakaryo
  • 93
  • 2
  • 2
  • 7
0

I removed from your "Grades" Constructor the input reference because it is useless to do it twice (at enterGradeNames you initilize it again). The problem was you closed the resource at the constructor and then tried to recreate it again.

public Grades(){
    len = 0;
    System.out.println("Enter the size of the grade array to be created");
    len = 4;
    gradeArray = new int[len];
    gradeNames = new String[len];
    enterGradeNames();
}
Orel Eraki
  • 11,940
  • 3
  • 28
  • 36