Home > OS >  Build a method to read a text file with multiple variables into an array without using ArrayList in
Build a method to read a text file with multiple variables into an array without using ArrayList in

Time:09-25

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]);
}
  • Related