Reputation: 52
I have a text file with student's names on one line, followed by 15 grades (each separated by 2 spaces & with a single space at the beginning of the line) on the next line.
Example:
John, Elton
89 97 91 94 82 96 98 67 69 97 87 90 100 80 92
Johnson, Kay
96 68 71 70 90 79 69 63 88 75 61 77 100 80 88
(More data...)
I need to read the line containing the student name and store the value in a String array, then read the following line of grades, storing the values in 2D Integer array. On each line of integers, the first 10 values are to be considered assignment grades while the last 5 values are exam grades (To be used later when computing student averages). My program crashes due to an "Input Mismatch Exception" when it attempts to read the line of integers after the first student name. Here's my code so far:
import java.io.*;
import java.util.*;
public class Grades
{
// Declare constants for array lengths
private static final int ROWS = 25;
private static final int COLS = 15;
public static void main(String[] args) throws IOException
{
// Create new two dimensional integer array to hold students assignment & exam grades
int[][] grades = new int[ROWS][COLS];
// Create new string array to hold student names
String[] students = new String[ROWS];
// Total number of students
int numStudents;
// Display your name
System.out.println( "YOUR NAME" );
// Fill the arrays
numStudents = fillArray( grades, students );
// Display the data that was just read in
display(grades, students, numStudents);
}
// The fillArray method opens & reads student name & grade data from a text file
private static int fillArray(int[][] sGrades, String[] sNames) throws IOException
{
// Students counter
int students = 0;
// Create the file
File studentGrades = new File("Grades.txt");
// Check that the file exists
if (!studentGrades.exists())
{
// Display error message and exit the program
System.out.println(studentGrades + " not found. Aborting.");
System.exit(0);
}
// Create scanner object to read from the file
Scanner gradeFile = new Scanner(studentGrades);
// Read data until the end of the file is reached or the array is full
while (gradeFile.hasNext() && students < sNames.length)
{
// Begin filling the array of student names starting with the first element
for ( int i = 0; i < ROWS; i++ )
{
// Store the students name into the array's current index
sNames[i] = gradeFile.nextLine();
// Increment the number of students
students++;
// Begin filling in the array of grades starting with the first element
/************* ERROR OCCURS HERE ********************/
for ( int j = 0; j < COLS; j++ )
// Store the grade into the array's current index
sGrades[i][j] = gradeFile.nextInt();
/************** *******************/
}
}
// Close the file
gradeFile.close();
// Return the total number of students
return students;
}
// The display method prints Each student's name, 10 assignment
// grades and 5 exam grades
// to the screen, separating each student by a blank line.
total number of students
private static void display(int[][] gradeArray, String [] studentArray, int totalStudents)
{
//
for ( int i = 0; i < totalStudents; i++)
{
System.out.println();
//
System.out.print("STUDENT: " + studentArray[i]);
System.out.print("\nASSIGNMENTS: ");
//
for ( int j = 0; j < 10; j++)
//
System.out.print(gradeArray[i][j] + " ");
//
System.out.print("\nEXAMS: ");
//
for ( int k = 10; k < COLS; k++)
//
System.out.print(gradeArray[i][k] + " ");
System.out.println();
}
The output from the 'display' method should look like this:
YOUR NAME
STUDENT: John, Elton
ASSIGNMENTS: 89 97 91 94 82 96 98 67 69 97
EXAMS: 87 90 100 80 92
STUDENT: Johnson, Kay
ASSIGNMENTS: 96 68 71 70 90 79 69 63 88 75
EXAMS: 61 77 100 80 88
(More output...)
Since the program crashes before I can see any output, I removed the following line of code that is trying to read the next Integer to see what is happening.
for ( int j = 0; j < COLS; j++ )
sGrades[i][j] = gradeFile.nextInt();
As I expected, each line of the file is read as a string and the value is stored in the array of student names resulting in output like this:
STUDENT: John, Elton
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0
STUDENT: 89 97 91 94 82 96 98 67 69 97 87 90 100 80 92
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0
STUDENT: Johnson, Kay
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0
STUDENT: 96 68 71 70 90 79 69 63 88 75 61 77 100 80 88
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0
(More output...)
My brain hurts trying to figure out where I'm going wrong. If I were to guess, I would think it has to do with the spaces separating each integer causing each line of grades to be interpreted as a String instead of an integer. Or is there something else I may have overlooked?
EDIT: I am limited to using more basic Java techniques for this program. I cannot use Array Lists, exception handling other than a throws
clause in the method headers. File-handling is limited to using the File
& Scanner
classes. No BufferReader
or StringReader
or FileReader
.
Upvotes: 1
Views: 1704
Reputation: 52
Thanks for everyone's input. I figured out the problem was an unnecessary for
loop to process student names. I modified my code in the fillArray()
method to look like this:
private static int fillArray(int[][] sGrades, String[] sNames) throws IOException
{
int students = 0; // Students counter
// Create the file
File studentGrades = new File("Grades.txt");
// Check that the file exists
if (!studentGrades.exists())
{
// Display error message and exit the program
System.out.println(studentGrades + " not found. Aborting.");
System.exit(0);
}
// Create scanner object to read from the file
Scanner gradeFile = new Scanner(studentGrades);
// Read data until the end of the file is reached or array is full
while (gradeFile.hasNext() && students < ROWS)
{
sNames[students] = gradeFile.nextLine();
for ( int i = 0; i < COLS; i++ )
sGrades[students][i] = gradeFile.nextInt();
students++;
gradeFile.nextLine();
}
// Close the file
gradeFile.close();
// Return the total number of students
return students;
}
And voila!
STUDENT: John, Elton
ASSIGNMENTS: 89 97 91 94 82 96 98 67 69 97
EXAMS: 87 90 100 80 92
STUDENT: Johnson, Kay
ASSIGNMENTS: 96 68 71 70 90 79 69 63 88 75
EXAMS: 61 77 100 80 88
STUDENT: Liston, Ed
ASSIGNMENTS: 78 98 98 85 96 96 64 60 81 61
EXAMS: 66 83 100 98 93
STUDENT: Kelly, Michael
ASSIGNMENTS: 72 64 76 76 86 100 69 87 76 79
EXAMS: 76 93 100 78 82
STUDENT: Presley, Elvis
ASSIGNMENTS: 92 94 100 50 82 79 72 75 78 85
EXAMS: 70 76 100 87 79
STUDENT: Hughes, Meghan
ASSIGNMENTS: 90 97 89 100 94 88 70 92 90 92
EXAMS: 91 84 100 94 71
STUDENT: Madonna
ASSIGNMENTS: 97 97 84 94 96 91 86 95 90 98
EXAMS: 93 91 100 98 96
STUDENT: Pacino, Al
ASSIGNMENTS: 73 71 77 70 89 100 82 0 90 77
EXAMS: 5 77 100 80 74
STUDENT: Bush, George W.
ASSIGNMENTS: 76 73 60 82 79 74 66 77 73 86
EXAMS: 70 78 100 77 90
STUDENT: Burke, Maggie
ASSIGNMENTS: 94 73 74 79 66 78 43 90 97 91
EXAMS: 87 79 100 67 90
STUDENT: Diesel, Vin
ASSIGNMENTS: 60 64 89 66 52 70 67 66 67 66
EXAMS: 55 73 100 75 45
STUDENT: Spiderman
ASSIGNMENTS: 89 75 91 99 91 80 100 98 91 78
EXAMS: 92 93 100 92 99
STUDENT: Baggins, Bilbo
ASSIGNMENTS: 82 81 55 89 71 74 35 68 86 96
EXAMS: 65 0 100 71 61
STUDENT: Williams, Serena
ASSIGNMENTS: 100 94 96 98 90 90 92 91 92 90
EXAMS: 88 94 100 82 92
STUDENT: Baggins, Frodo
ASSIGNMENTS: 68 78 80 73 83 74 74 67 39 81
EXAMS: 65 88 100 68 92
STUDENT: Potter, Harry
ASSIGNMENTS: 87 61 78 89 86 80 70 72 77 83
EXAMS: 65 93 100 86 67
STUDENT: Cianci, Buddy
ASSIGNMENTS: 98 70 60 91 67 81 89 64 70 77
EXAMS: 62 77 100 92 76
STUDENT: Basilico, Anthony
ASSIGNMENTS: 67 69 76 76 75 67 83 83 88 75
EXAMS: 63 63 100 82 100
STUDENT: Clapton, Eric
ASSIGNMENTS: 100 85 64 89 83 68 84 91 84 66
EXAMS: 81 84 100 100 95
STUDENT: Lennon, John
ASSIGNMENTS: 88 65 84 68 80 90 61 62 88 75
EXAMS: 74 75 100 80 76
Upvotes: 0
Reputation: 2914
Try out something like this
private static final int COLS = 15;
public static void computeScores() throws IOException {
int totalStudents = 0, totalMarks = 0;
String[] lines = new String(Files.readAllBytes(Paths.get("data.txt"))).split("[\\r\\n]+");
String[] sNames = new String[lines.length / 2];
int[][] grades = new int[lines.length / 2][COLS];
if (lines.length > 0) {
for (int i = 0; i < lines.length; i++) {
if (i % 2 == 0) {
sNames[totalStudents] = lines[i];
totalStudents++;
} else {
String[] marks = lines[i].split(" ");
for (int j = 0; j < marks.length; j++)
grades[totalMarks][j] = Integer.parseInt(marks[j].trim());
totalMarks++;
}
}
}
}
//go ahead and print out your values the usual way you've been doing it
for (int i = 0; i < totalStudents; i++) {
System.out.println();
//
System.out.print("STUDENT: " + sNames[i]);
System.out.print("\nASSIGNMENTS: ");
//
for (int j = 0; j < 10; j++)
//
System.out.print(grades[i][j] + " ");
//
System.out.print("\nEXAMS: ");
//
for (int k = 10; k < COLS; k++)
//
System.out.print(grades[i][k] + " ");
System.out.println();
}
This should print just fine
Upvotes: 0
Reputation: 1289
Use Integer.parseInt(gradeFile.next())
instead of gradeFile.nextInt()
It works like this:
/************* ERROR OCCURS HERE ********************/
for (int j = 0; j < COLS; j++) {
// Store the grade into the array's current index
sGrades[i][j] = Integer.parseInt(gradeFile.next());
/************** *******************/
}
if (gradeFile.hasNext())
gradeFile.nextLine();
Upvotes: 0
Reputation: 1468
Well I've written an application to do exactly what you want.
Here it is:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Main {
//Aka rows
private static final int NO_STUDENTS = 25;
//Grades per student. Aka columns.
private static final int NO_GRADES = 15;
//Names of all the students
private final String[] STUDENTS = new String[NO_STUDENTS];
//The students grades
private final int[][] GRADES = new int[NO_STUDENTS][NO_GRADES];
/**
* Runs the application
*/
public Main() {
try {
//Writes to the arrays from the text file
parseReults("Results.txt");
//Prints the results in the format
printResults();
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* Parses the students names and grades from a text file and writes them to
* the arrays.
*
* @param resultsFile
*/
private void parseReults(String resultsFile) throws IOException {
BufferedReader reader = new BufferedReader(
new StringReader(getTextFileContents(resultsFile)));
int lineNo = 0;
int studentNo = 0;
int gradeNo = 0;
String line;
//Reads over every line in the file
while ((line = reader.readLine()) != null) {
//Is the line number odd, if so read students name else read
//the grades
if (lineNo % 2 == 0) {
STUDENTS[studentNo] = line;
studentNo++;
} else {
GRADES[gradeNo] = getGrades(line);
gradeNo++;
}
lineNo++;
}
}
/**
* Prints the results from the arrays.
*/
private void printResults() {
System.out.println("YOUR NAME\n");
for (int i = 0; i < STUDENTS.length; i++) {
System.out.println("STUDENT: " + STUDENTS[i]);
String assignments = "";
for (int j = 0; j < 9; j++) {
assignments += GRADES[i][j] + " ";
}
System.out.println("ASSIGNMENTS: " + assignments);
String exams = "";
for (int k = 9; k < 15; k++) {
exams += GRADES[i][k] + " ";
}
System.out.println("EXAMS: " + exams);
System.out.println("");
}
}
public static void main(String[] args) throws IOException {
Main m = new Main();
}
/**
* Parses all the students grades from one line of text into an integer
* array containing all the grades.
*
* @param gradesLine
* @return
*/
private static int[] getGrades(String gradesLine) {
try {
int[] grades = new int[NO_GRADES];
StringReader reader = new StringReader(gradesLine);
reader.read();//Get rid of the first space
for (int i = 0; i < NO_GRADES; i++) {
String grade = "";
char letter;
while ((letter = (char) reader.read()) != ' ') {
if (letter == '\n' || letter == (char) 65535) {
break;
}
grade += letter;
}
reader.read();//Get red of the second space
grades[i] = Integer.parseInt(grade);
}
return grades;
} catch (IOException ex) {
//Isn't happening
}
return null;//Won't happen
}
/**
* Reads an entire text file.
*
* @param fileName the name of the file
* @return the file contents
*/
private static String getTextFileContents(String fileName)
throws FileNotFoundException, IOException {
String contents = "";
try (BufferedReader reader = new BufferedReader(
new FileReader(new File(fileName)))) {
String line;
while ((line = reader.readLine()) != null) {
contents += line + "\n";
}
}
return contents;
}
}
This is the "Results.txt" file:
John, Elton
89 97 91 94 82 96 98 67 69 97 87 90 100 80 92
Johnson, Kay
96 68 71 70 90 79 69 63 88 75 61 77 100 80 88
Amanda, Grey
35 15 44 88 95 84 85 45 15 95 11 46 98 100 88
And finally, this is the output:
YOUR NAME
STUDENT: John, Elton
ASSIGNMENTS: 89 97 91 4 82 96 98 67 69
EXAMS: 97 87 90 100 80 92
STUDENT: Johnson, Kay
ASSIGNMENTS: 96 68 71 70 90 79 69 63 88
EXAMS: 75 61 77 100 80 88
STUDENT: Amanda, Grey
ASSIGNMENTS: 35 15 44 88 95 84 85 45 15
EXAMS: 95 11 46 98 100 88
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
STUDENT: null
ASSIGNMENTS: 0 0 0 0 0 0 0 0 0
EXAMS: 0 0 0 0 0 0
Now, for how it works:
From the main(String[])
method, it initializes a new instance of Main
.
In the constructor of Main
, The parseResults(String fileName)
method is called which reads the file and parses the results. Then, the printResults()
method is called, which, as you can guess by the name, prints the results.
The parseResults()
method:
This is where all the magic happens. It begins by reading the whole file and then iterating over it line by line. If the line number of the line it's reading is an even number, it will take the text from the line and append it to the next row of the STUDENTS
array. If the line number is odd, it knows this line holds the grades of the last student, so it calls the getGrades()
method which parses a line of grades into an integer array holding all the grades from the line of text, then it appends the grades integer array to the next row of the GRADES
array.
Upvotes: 0
Reputation: 37
Surround your filling with try and catch statements as follow:
try{
sNames[i] = gradeFile.nextLine();
}catch(Exception NoSuchElementException){
}
And write the for loop which generates the error like that :
for ( int j = 0; j < COLS; j++ ){
try{
sGrades[i][j]=gradeFile.nextInt() ;
}catch(Exception NoSuchElementException){
}
}
try{
gradeFile.nextLine();
}catch(Exception NoSuchElementException){
}
The last gradeFile.nextLine() was missing after your for loop(that adds integers), I added it with a try and catch statement Tell me if it works :)
Upvotes: 0