索引超出范围(文件读取)

时间:2015-08-01 06:16:28

标签: java indexing printf range out

我试图让我的程序读取学生对多项选择考试(单独的文件,包括在内)的问题的回答,然后根据文件打印出信息。

程序的输出应包括学生分数的完整列表(正确答案的数量,错误答案和空白答案),但我收到此错误:

  

线程“main”中的异常java.lang.StringIndexOutOfBoundsException:
  字符串索引超出范围:9
          在java.lang.String.charAt(String.java:658)
          在ExamAnalysis.basicAnalysis(ExamAnalysis.java:38)
          在ExamAnalysis.main(ExamAnalysis.java:31)

另外,如何使用printf打印常规int?现在,我正在为一些应该是整数的变量使用双精度因为我无法弄清楚如何打印整数。

代码:

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

public class ExamAnalysis {
    public static void main(String[] args) throws FileNotFoundException {
        Scanner keyboard = new Scanner(System.in);
        double numStudents = 0;
        System.out.print("Welcome to Exam Analysis. Let's begin ...\n"
                + "\nPlease type the correct answers to the exam questions,\n"
                + "one right after the other: ");
        // String corrAns = keyboard.next();
        String corrAns = "ABCEDBACED";
        System.out
                .print("\nWhat is the name of the file containing each student's\n"
                        + "responses to the 10 questions?");
        // File f = new File (keyboard.next());
        File f = new File("exams.dat");
        Scanner fileR1 = new Scanner(f);
        while (fileR1.hasNextLine()) {
            System.out.printf("Student #%.0f's responses: %s\n",
                    numStudents + 1, fileR1.nextLine());
            numStudents++;
        }
        System.out
                .printf("We have reached \"end of file!\"\n"
                        + "\nThank you for the data on the %.0f students. Here's the analysis:\n",
                        numStudents);
        String[] studentAns = new String[(int) numStudents];
        Scanner fileR2 = new Scanner(f);
        for (int num = 0; num < numStudents; num++) {
            String ans = fileR2.nextLine();
            studentAns[num] = ans;
        }
        int numStud = (int) numStudents;
        basicAnalysis(numStud, studentAns, corrAns);
    }

    public static void basicAnalysis(int numStud, String[] studentAns,
            String corrAns) {
        int[][] bArray = new int[numStud][3];
        for (int num = 0; num < numStud; num++) {
            String ansString = studentAns[num];
            for (int charNum = 0; charNum < corrAns.length(); charNum++) {
                if (ansString.charAt(charNum) == ' ') {
                    bArray[num][2] += 1;
                } else if (ansString.charAt(charNum) == corrAns.charAt(charNum)) {
                    bArray[num][0] += 1;
                } else {
                    bArray[num][1] += 1;
                }
            }
        }
        System.out.println(Arrays.deepToString(bArray));
        System.out.println("Student #    Correct    Incorrect    Blank\n"
                + "~~~~~~~~~    ~~~~~~~    ~~~~~~~~~    ~~~~~");
        for (int numb = 0; numb < numStud; numb++) {
            System.out.printf("%5.0f %11d %11d %8d\n", (double) numb + 1,
                    bArray[numb][0], bArray[numb][1], bArray[numb][2]);
        }
    }
}

我正在阅读的文件是:

ABDEBBAC D
ABCE CACED
  DCE AEDC
ABCEB ACED
BBCEDBACED
DBCE CACED
ABCE CA E
BBE  CACED
ABCEDBACED

我很确定我的方法basicAnalysis运行正常。 任何帮助将不胜感激。感谢

2 个答案:

答案 0 :(得分:3)

我不确定我是否完全理解您要完成的任务,但如果您在exams.dat中的所有记录必须具有相同的长度,那么从底部开始的第3个记录缺少一个字符。 我指的是那条记录:

ABCE CA E

所有其他记录长度为10个字符,但该记录只有9个字符。

<强>更新

为了使其更加健壮,您似乎需要考虑到学生的答案数量可能与预期(正确)答案不同,以及两种方式(即学生的答案少于或多于预期答案) )。

我会将内部for循环体的内容更改为:

if (charNum >= ansString.length()) {
                bArray[num][2] += 1;
            } else if (ansString.charAt(charNum) == ' ') {
                bArray[num][2] += 1;
            } else if (ansString.charAt(charNum) == corrAns.charAt(charNum)) {
                bArray[num][0] += 1;
            } else {
                bArray[num][1] += 1;
            }

如果您想要增加错误答案的数量,如果学生回答超过预期,您只需要在内部for循环之前或之后添加:

if (ansString.length() > corrAns.length())
            bArray[num][2] += (ansString.length() - corrAns.length());

答案 1 :(得分:2)

输入文件的问题

而不是

   for (int charNum = 0; charNum < corrAns.length(); charNum++)

每次使用corrAns查看时。查看ansString。如果您有更多记录,很难更改包含9个字符的内容。

使用

  for (int charNum = 0; charNum < ansString.length(); charNum++) {