Murder face Murder face - 7 months ago 9
Java Question

How to get 2 separate number averages from a text file?

I am new to the java language and I can't figure out how to read one line at a time from a text file and get the average for that line.

My working code so far gets the average for the whole file:

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

public class NumAverage {
public static void main(String[] args) throws IOException {
Scanner keyboard = new Scanner(System.in);

File myFile = new File("Num.txt");
Scanner inputFile = new Scanner(myFile);

int numbersCounter = 0;
int sum = 0;

while (inputFile.hasNext()) {
int numList = inputFile.nextInt();

sum = sum + numList;
numbersCounter++;
}

System.out.println("Average: " + (sum/numbersCounter));

inputFile.close();
}
}


This what the text file looks like

1 2 3 4
5 6 7 8

Answer

You have to learn Java's streams API (knowing decorator pattern simplifies understanding it).

For your case, we can do:

FileInputStream stream = new FileInputStream("nums.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
String line;

while((line = reader.readLine()) != null) {
    StringTokenizer tokenizer = new StringTokenizer(line, " ");
    int tokens = tokenizer.countTokens();
    float average = 0;

    while(tokenizer.hasMoreTokens()) {
        String token = tokenizer.nextToken();
        int value = Integer.valueOf(token);
        average += value;
    }

    System.out.println(average / tokens);
}

In the first line I'm creating a FileInputStream that allows us to read from the file.

In the second line I am decorating stream as InputStreamReader and then as BufferedReader (the second one has great API for reading input line by line).

Then I am iterating over your file line by line (using readLine() method in loop) and using StringTokenizer I am splitting the line into tokens.

In the second loop I'm doing all necessary calculations.

Of course you need to remember about exceptions (I've ommited them for example simplicity).

One more thing that is worth to mention - you need to be aware that countTokens() method should be used before consuming tokens - otherwise it will return improper value (it returns a number of how many you can call nextToken() before receiving exception).