Ernesto Jorge
Ernesto Jorge

Reputation: 25

Calculating average from a file gives unexpected output

I'm relatively new to java and I wonder why this code is not giving the desire result. I have to read a text file with the following format:

Name Last Name, 92 82 88 96 78
name Last Name, 87 93 85 82 94

Basically name + last name, and then 5 scores. I need to read the file and print to the console the name follow by the average of each person scores. The number of scores will always be 5 but the number of persons it is not specified. My code throws a NoSuchElementException and gives me wrong results for the averages. Take a look:

package nameavgfile;
import java.util.Scanner;
import java.io.*;


public class NameAvgFile {


    public static void main(String[] args) {
        Scanner inFile;
        final int count = 5;
        double score = 0;
        try{
            inFile = new Scanner(new File("data.txt"));
            while(inFile.hasNextLine()){
                String name = inFile.next()+" "+inFile.next();
                while(inFile.hasNextDouble()){
                    score += inFile.nextDouble();
                    System.out.println(name+" "+score/count);
                }
            }
        }catch(IOException e){
            System.out.println(e.getMessage());
        }
    }
}

Upvotes: 1

Views: 88

Answers (2)

Bohemian
Bohemian

Reputation: 425033

Problem 1:

You're not resetting the score to zero when you start a new line.

Move this line:

double score = 0;

to the first line inside the outer (line) loop.

Problem 2:

You're printing the average every time you read a score. Instead, print the average after you've read all the scores, so move this line:

System.out.println(name+" "+score/count);

outside the inner (score) loop to the last line of the outer (line) loop.

Problem 3:

You're not consuming the new line characters after the scores. Add this line to the end of your loop:

inFile.nextLine();

Java 8 has some stuff that can make this task easier. Try this instead:

public static void main(String[] args) throws IOException {
    Files.lines(Paths.get("c:/tmp/data.txt")).forEach(NameAvgFile::processLine);
}

private static void processLine(String line) {
    String[] parts = line.split(" ");
    System.out.println(parts[0] + " " + parts[1] + " " + sum(Arrays.copyOfRange(parts, 2, parts.length)));
}

private static double sum(String[] doubleStrings) {
    return Arrays.stream(doubleStrings).mapToDouble(Double::parseDouble).average().getAsDouble();
}

Upvotes: 2

Abdelhak
Abdelhak

Reputation: 8387

Try just to put System.out.println(name+" "+score/count); inside the first loop like below:

   public static void main(String[] args) {
       Scanner inFile;
      final int count = 5;
       double score = 0;
       try{
           inFile = new Scanner(new File("C:\\temp\\file.txt"));
           while(inFile.hasNextLine()){
                String name = inFile.next()+" "+inFile.next();
                while(inFile.hasNextDouble()){
                     score += inFile.nextDouble(); 
                }
                System.out.println(name+" "+score/count);
            }
        }catch(IOException e){
            System.out.println(e.getMessage());
        }
    }

Upvotes: 0

Related Questions