I have been instructed to build a Student Class to include different variables including String name, int marksforphysic etc. Then I aim to build a method to read a text file which contains these data without using ArrayList. After that, I need to sort the array. But I face the problem in putting the data of the txt file into an array.
The below are the codes:
public class Main2{
public static void main(String[] args) throws FileNotFoundException {
String filename = "students.txt";
Student[] record = readData(filename);
record = new Student [record.length];
for(int i = 0; i < record.length; i ){
System.out.println(record[i]);
}
}
//Method for read data from the .txt file into an array
private static Student[] readData(String filename){
int arraysize = 0;
try{
Scanner s1 = new Scanner(new File(filename));
//Count elements in the file
while(s1.hasNext()){
arraysize ;
s1.next();
}
//Create an array and copy the elements into it
Student[] studentRecord = new Student[arraysize];
Scanner s2 = new Scanner(new File(filename));
for(int i = 0; i < arraysize; i ){
studentRecord[i].name = s2.next();
studentRecord[i].physic = s2.nextInt();
studentRecord[i].chemistry = s2.nextInt();
studentRecord[i].math = s2.nextInt();
studentRecord[i].average = (double)(studentRecord[i].physic studentRecord[i].chemistry studentRecord[i].math)/3;
// double roundedAvg = Math.round(average * 100.0) / 100.0;
// studentRecord[i].average = Math.round((physic chemistry math)/3 * 100.0)/100.0;
}
return studentRecord;
}
catch(FileNotFoundException e){
}
return null;
}
}
The text file include record as below:
Jack 77 84 93
Tod 84 86 80
Name marksP marksC marksM
The code can be compiled but when I run the code. It shows
Exception in thread "main" java.lang.NullPointerException: Cannot assign field "name" because "<local3>[<local5>]" is null
at Main2.readData(Main2.java:40)
at Main2.main(Main2.java:10)
Is it because of the Student Class ? but I have initialized the Student Class attribute as:
public Student(String name, int m1, int m2, int m3, double avg){
this.name = name;
int.mark1 = m1;
...
}
What did I do incorrectly ? How do I fix the code ? The name should not be null when I have initialized in the Student Class.
CodePudding user response:
In your for
loop, where you read the data from the file, your studentRecord
contains no actual Student
objects yet. It is only a placeholder so far, which can hold the specified amount of Student
objects. So you need to actually create Student
objects to store in the specified array.
For this, read the data, store it temporarily in variables and then create each Student
object via the constructor you already have.
So it should actually look something like this:
for(int i = 0; i < arraysize; i ){
String name = s2.next();
int physic = s2.nextInt();
int chemistry = s2.nextInt();
int math = s2.nextInt();
double average = (double)(physic chemistry math) / 3;
Student myStudent = new Student (name, physic, chemistry, math, average);
studentRecord[i] = myStudent;
}
Also, you are calculating your arraysize incorrectly as of now. You will need to count the lines, not each individual token. Something more like this:
while(s1.hasNextLine()){
arraysize ;
s1.nextLine();
}
CodePudding user response:
I think your problem is that you don't fully understand what is happening whe you execute
Student[] studentRecord = new Student[arraysize];
This will create an array called studentRecord
that has a specific size. What it won't do is create any objects of type Student to put into this array. Your array will contain nothing but nulls.
To fix it you'll need something like:
for(int i = 0; i < arraysize; i ) {
studentRecord[i] = new Student();
studentRecord[i].name = s2.next();
CodePudding user response:
The first issue I've found is with the way you are counting the number of students you have in the file. If you know that amount of lines in your students.txt file exactly equals the number of students, (No labels or anything that can stretch over multiple lines) then you can count it like this:
while(scan.hasNext()) {
lines ;
scan.nextLine();
}
The second problem is with the array creation. When you initialize an array like this:
final Student[] students = new Students[length];
It will create the array, it will be full of null elements: [null, null, null,... ]
. But these null elements are not your Student objects. So you can just fill the array with empty objects and change their properties later in code:
final Student[] students = new Students[length];
Arrays.fill(students, new Student("default", 100, 100, 100);
Tip: You can move the calculation of the average to the constructor of Student class like this and try to use smaller or larger date types depending on the use case link to read more is here!:
public Student(String name, byte physics, byte chemistry, byte math) {
this.name = name;
this.physics = physics;
this.chemistry = chemistry;
this.math = math;
this.avg = (math chemistry physics) / 3.0;
}
Now we don't need to set or overwrite variables for the Student object. When there is repeating code there is probably a better way to write it (not all the time).
for (int i = 0; i < lines; i ) {
students[i] = new Student(fileScanner.next(), fileScanner.nextByte(), fileScanner.nextByte(), fileScanner.nextByte());
System.out.println(students[i]);
}