I'm working on a school project.
I'm trying to gather data from a .txt file with Scanner
but I get an error when I want to use the Scanner
to initiate variable.
My code
File etudiant = new File("./data/etudiants.txt");
File personnel = new File("./data/personnel.txt");
Scanner scEtudiant = new Scanner(etudiant);
Scanner scPersonnel = new Scanner(personnel);
//creation liste etudiant
while (scEtudiant.hasNextLine()) {
int num = scEtudiant.nextInt();
String nom = scEtudiant.next();
String prenom = scEtudiant.next();
String telephone = scEtudiant.next();
String email = scEtudiant.next();
int annee = scEtudiant.nextInt();
individuListe.put(num, new Etudiant(num, nom, prenom, telephone, email, annee));
}
scEtudiant.close();
My error
Exception in thread "main" java.util.NoSuchElementException
at java.base/java.util.Scanner.throwFor(Scanner.java:937)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
at gestion.Gala.<init>(Gala.java:37)
at gestion.Main.main(Main.java:7)
If I remove the variable and put some System.out.println()
instead it display the data properly but still outputs this error.
CodePudding user response:
Read and analyze the stacktrace
The error-output / stacktrace shows invocation of Scanner.nextInt()
as causing the NoSuchElementException
. See line 37 of your code, where nextInt()
was called, probably one of those two:
int num = scEtudiant.nextInt();
int annee = scEtudiant.nextInt();
Learn about NoSuchElementException
This exception is thrown by all next..()
methods in class Scanner
.
It indicates that the expected next token (here of numerical type Int
) was not found in the scanned text-stream.
See JavaDoc of nextInt()
for Throws description:
Throws:
InputMismatchException
- if the next token does not match the Integer regular expression, or is out of range
NoSuchElementException
- if input is exhausted
IllegalStateException
- if this scanner is closed
To prevent this Exception when calling next..()
methods you can test on the presence of a next element with hasNext()
, hasNext..()
or hasNextLine()
predicate-methods.
See also:
- Baeldung tutorial: Java Scanner hasNext() vs. hasNextLine()
Robust solution: Prevent the error with guard statements
use hasNextInt()
to test if there is a next element of type int
and so on.
while (scEtudiant.hasNextLine()) { // each student record on a new line
if (!scEtudiant.hasNextInt()) { // guard breaks loop if no int
break;
}
int num = scEtudiant.nextInt();
if (!scEtudiant.hasNext()) { // guard breaks loop if no String
break;
}
String nom = scEtudiant.next();
if (!scEtudiant.hasNext()) { // guard breaks loop if no String
break;
}
String prenom = scEtudiant.next();
String telephone = ""; // not available, default to empty
if (scEtudiant.hasNext()) { // optional: if string available
telephone = scEtudiant.next();
}
String email = ""; // not available, default to empty
if (scEtudiant.hasNext()) { // optional: if string available
email = scEtudiant.next();
}
if (!scEtudiant.hasNextInt()) { // guard breaks loop if no int
break;
}
int annee = scEtudiant.nextInt();
var etudiant = new Etudiant(num, nom, prenom, telephone, email, annee)
individuListe.put(etudiant.getNum(), etudiant);
}
CodePudding user response:
You are not sharing the whole class
for that reason I can not say for sure but can guess that you are not giving the default
values to the primitive variables
in the while
loop. So what you should do first declare them outside the function give them default value and then use it inside while
loop
CodePudding user response:
Change the while
loop condition to scEtudiant.hasNextInt()
?
Typically you use a hasNextXXX
method of Scanner
before the corresponding nextXXX
method.