I'm a beginner taking Intro to Computer Science and I'm working with java. I get the following error in this program when trying to read from multiple txt files in the getLetterGrade method:
Exception in thread "main" java.lang.IllegalStateException: Scanner closed
import java.util.Scanner;
import java.io.*;
public class Exam
{
private int grade;
private float examAvg;
private String name;
private File exam1Data;
private File exam2Data;
private File namesData;
private Scanner inFileExam1;
private Scanner inFileExam2;
private Scanner inFileName;
//constructor
public Exam() throws IOException
{
exam1Data = new File("exam1.txt");
exam2Data = new File("exam2.txt");
namesData = new File("names.txt");
inFileExam1 = new Scanner(exam1Data);
inFileExam2 = new Scanner(exam2Data);
inFileName = new Scanner(namesData);
}
public float getExam1Avg()
{
examAvg = 0;
while (inFileExam1.hasNext()) {
grade = inFileExam1.nextInt();
examAvg += grade;
}
inFileExam1.close();
examAvg = (float)(examAvg / 25.0);
return examAvg;
}
public float getExam2Avg()
{
examAvg = 0;
while (inFileExam2.hasNext()) {
grade = inFileExam2.nextInt();
examAvg += grade;
}
inFileExam2.close();
examAvg = (float)(examAvg / 25.0);
return examAvg;
}
//method that finds the letter grade given a student name and
//the exam number
public char getLetterGrade(String inputName, int examNum)
{
char letter;
int count = 1;
//inputName = inputName.toLowerCase();
do {
if (inFileName.hasNext()){
name = inFileName.nextLine();
}
count++;
} while (inFileName.hasNext() && !name.equalsIgnoreCase(inputName));
inFileName.close();
if (!name.equalsIgnoreCase(inputName)) {
return 'x';
}
if (examNum == 1) {
for (int i = 1; i <= count && inFileExam1.hasNextInt(); i++) {
grade = inFileExam1.nextInt();
}
inFileExam1.close();
}
else if (examNum == 2) {
for (int i = 1; i <= count && inFileExam2.hasNextInt(); i++) {
grade = inFileExam2.nextInt();
}
inFileExam2.close();
}
else {
return 'x';
}
if (grade >= 90) {
letter = 'A';
}
else if (grade < 90 && grade >= 80) {
letter = 'B';
}
else if (grade < 80 && grade >= 70) {
letter = 'C';
}
else if (grade < 70 && grade >= 60) {
letter = 'D';
}
else {
letter = 'F';
}
return letter;
}
}
The error occurs at the following line:
for (int i = 1; i <= count && inFileExam1.hasNextInt(); i++) {
Please help!!
Here is the main class:
import java.util.Scanner;
import java.io.*;
public class ExamAverages
{
public static void main(String[] args) throws IOException
{
Exam exam = new Exam();
System.out.println(exam.getExam1Avg());
System.out.println(exam.getExam2Avg());
System.out.println(exam.getLetterGrade("name", 1));
}
you are closing your scanner
inFileName.close();
and then trying to use it again without opening as like:
inFileName = new Scanner(..);
EDIT1 It does not fail for me, but maybe i have missed some stuff (I still don't know how exactly you are willing to read these files, how they relate to each other)
public char getLetterGrade(String inputName, int examNum) {
char letter;
int count = 0;
do {
if (inFileName.hasNext()) {
name = inFileName.nextLine();
}
count++;
} while (inFileName.hasNext() && !name.equalsIgnoreCase(inputName));
if (!name.equalsIgnoreCase(inputName)) {
return 'x';
}
if (examNum == 1) {
for (int i = 1; i <= count && inFileExam1.hasNextInt(); i++) {
grade = inFileExam1.nextInt();
}
inFileExam1.close();
} else if (examNum == 2) {
for (int i = 1; i <= count && inFileExam2.hasNextInt(); i++) {
grade = inFileExam2.nextInt();
}
inFileExam2.close();
} else {
return 'x';
}
if (grade >= 90) {
letter = 'A';
} else if (grade < 90 && grade >= 80) {
letter = 'B';
} else if (grade < 80 && grade >= 70) {
letter = 'C';
} else if (grade < 70 && grade >= 60) {
letter = 'D';
} else {
letter = 'F';
}
return letter;
}
First of all, you're resetting grade
every time you read a line, and you aren't doing anything with it, so that part of the code is useless.
But to answer your question:
According to the API, Scanner
only returns an IllegalStateException
after the object is closed using Scanner.close()
or is somehow closed by the system.
Try moving your Scanner
declaration for inFileExam1
next to where you are using it, like this:
if (examNum == 1) {
inFileExam1 = new Scanner(exam1Data); // Add this
for (int i = 1; i <= count && inFileExam1.hasNextInt(); i++) {
grade = inFileExam1.nextInt();
}
inFileExam1.close();
}
else if (examNum == 2) {
inFileExam2 = new Scanner(exam2Data); // And this
for (int i = 1; i <= count && inFileExam2.hasNextInt(); i++) {
grade = inFileExam2.nextInt();
}
inFileExam2.close();
}
}
You don't include the code that has your main method, but I'm going to make an educated guess that you construct a new Exam
object in it, and call getLetterGrade
more than once. Since you open your Scanners
in the constructor, and close them after reading, the second time you call getLetterGrade
you will see an IllegalStateException
.
If this psychic reading is inaccurate, can you please update your post with the contents of main(String[] args)
?
EDIT: After your latest edit I see that you call the getExam1Avg
method before calling getLetterGrade
. Since getExam1Avg
calls close
on your Scanner
you get an IllegalStateException when calling the other method. You need to either instantiate a new scanner for each method call or otherwise reset the scanners after each method is complete.
Your error is in getAverageExam1Avg
and the other one. Instead of closing your Scanner
s in the getLetterGrade
method, you should keep them open and add a close
method like this:
public void close() {
inFileName.close();
inFileExam1.close();
inFileExam2.close();
}
Make sure to add the proper exceptions into that code.
The reason it is failing now is because you haven't opened the Scanners. Un-comment the instantiations in the constructor.
If this doesn't work, I have no idea what will.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.