Чтение данных из нескольких текстовых файлов в Java - PullRequest
1 голос
/ 06 декабря 2011

Я новичок в изучении компьютерных наук и работаю с Java. Я получаю следующую ошибку в этой программе при попытке чтения из нескольких текстовых файлов в методе getLetterGrade:

Исключение в потоке "main" java.lang.IllegalStateException: Сканер закрыт

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;
    }
}

Ошибка возникает в следующей строке:

for (int i = 1; i <= count && inFileExam1.hasNextInt(); i++) {

Пожалуйста, помогите !!

Вот основной класс:

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));
}

Ответы [ 4 ]

0 голосов
/ 06 декабря 2011

Ваша ошибка в getAverageExam1Avg и другой. Вместо того, чтобы закрывать ваши Scanner s в методе getLetterGrade, вы должны оставить их открытыми и добавить метод close, подобный этому:

public void close() {
    inFileName.close();
    inFileExam1.close();
    inFileExam2.close();
}

Убедитесь, что добавили правильные исключения в этот код.

Причиной сбоя сейчас является то, что вы не открыли сканеры. Не комментируйте экземпляры в конструкторе.

Если это не сработает, я понятия не имею, что будет.

0 голосов
/ 06 декабря 2011

Прежде всего, вы сбрасываете grade каждый раз, когда читаете строку, и ничего с ней не делаете, так что часть кода бесполезна.

Но чтобы ответить на ваш вопрос:

Согласно API, Scanner возвращает IllegalStateException только после того, как объект закрыт с помощью Scanner.close() или каким-либо образом закрыт системой.

Попробуйте переместить объявление Scanner для inFileExam1 рядом с тем местом, где вы его используете, например:

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();
    }
}
0 голосов
/ 06 декабря 2011

Вы не включаете код, содержащий ваш основной метод, но я собираюсь сделать обоснованное предположение, что вы создаете в нем новый объект Exam и вызываете getLetterGrade более одного раза. Поскольку вы открываете Scanners в конструкторе и закрываете их после чтения, в секунду раз, когда вы позвоните getLetterGrade, вы увидите IllegalStateException.

Если это экстрасенсорное чтение неточно, можете ли вы обновить свое сообщение с содержанием main(String[] args)?

РЕДАКТИРОВАНИЕ: После вашего последнего редактирования я вижу, что вы вызываете метод getExam1Avg перед вызовом getLetterGrade. Поскольку getExam1Avg вызывает close на вашем Scanner, вы получаете IllegalStateException при вызове другого метода. Вам нужно либо создавать новый сканер для каждого вызова метода, либо иным образом сбрасывать сканеры после завершения каждого метода.

0 голосов
/ 06 декабря 2011

вы закрываете свой сканер

inFileName.close();

и затем пытаетесь использовать его снова, не открывая, как:

inFileName = new Scanner(..); 

EDIT1 Это не дает сбоя дляя, но, возможно, я пропустил некоторые вещи (я до сих пор не знаю, как именно вы хотите читать эти файлы, как они связаны друг с другом)

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...