-1

I have been practicing questions out of a textbook that I downloaded online, and I was doing a program in the book which asked to write a program that searches a file of numbers and displays the largest number, smallest number and the average of all the numbers. The question also said to use numbers of type double that are written using writeDouble.

I have been able to all of which was required, except getting the average. I know that what I attempted when I tried to get the average of the numbers is incorrect, but I wanted to know if something to the effect of what I did exists, or if not, how I could obtain the average of the numbers without using an array? Here is my code

  public static void main(String[] args) {

    Scanner keyboard=new Scanner(System.in);

    System.out.println("Enter file name to be written");
    String file=keyboard.next();

    File fileName=new File(file);

    try{
        FileOutputStream fo=new FileOutputStream(fileName);
        ObjectOutputStream output=new ObjectOutputStream(fo);

        System.out.println("Enter numbers");
        System.out.println("enter q to quit");

        String number;

        do
        { 
            number=keyboard.next();
            if(number.equals("q")){
                output.writeUTF(number);
            }
            else{
                double new_number = Double.parseDouble(number);
                output.writeDouble(new_number);
            }   
        }
        while (!number.equals("q"));

        if(number.equals("q")){
            System.out.println("numbers were written to: "+fileName);
            output.close();
            fo.close();
        }
    }
    catch(FileNotFoundException e){
    }
    catch(IOException e){

    }

    double num=0;
    double num2=0;
    double num_check=0;
    double num3=999999999999999999999.99999;
    int count=0;
    System.out.println("Now the program starts");

    try{
        FileInputStream fi=new FileInputStream(fileName);
        ObjectInputStream input=new ObjectInputStream(fi);

        long file_length=fileName.length();

        for(int i=0;i<file_length;i++){

            num=input.readDouble();
            if(num>=0){
            System.out.println(num);
            }
            if(num>num_check){
                num_check=num;
            }
            else if(num<num3){
                num3=num;
            }
            count++;

        //Here is my attempt at getting the average

        double num_ave=num+num(i+1);
        double average=num_ave/count;
        System.out.println(average);
        System.out.println("Average of all the numbers is: "+average);**
        }
        input.close();
        fi.close();
    }

    catch(FileNotFoundException e){  
    }
    catch(EOFException e){

        System.out.println("Largest number: "+num_check);
        System.out.println("Smallest number: "+num3);

    }
    catch(IOException e){  
    }
}

}

Naa-ilah Daniels
  • 85
  • 1
  • 2
  • 10
  • Sum and count, then divide sum by count. – laune Jan 11 '15 at 13:51
  • 1
    First comment, without correct variable naming this code is illegible. Second comment, `num3` seems to be set to a random large number - any reason not to use `Double.MAX_VALUE`? Your main issue seems to be not understanding your own formatting and putting the averaging code _inside_ the `for` loop. – Boris the Spider Jan 11 '15 at 13:51
  • @laune What do you mean, how would I do this? – Naa-ilah Daniels Jan 11 '15 at 13:53
  • You can't determine a file's length from the length of its name `long file_length=fileName.length();` – laune Jan 11 '15 at 13:57
  • I think that this exercise in the textbook was intended to make the reader find a solution. Asking for a solution on stackoverflow is perhaps not the thing to do ? – bdulac Jan 11 '15 at 15:25

3 Answers3

1
  FileInputStream fis = new FileInputStream(fileName);
  try ( Scanner scanner = new Scanner( fis ) ){
    double sum = 0;
    int count = 0;
    while( scanner.hasNextDouble() ){
      double num = scanner.nextDouble();
      count++;
      sum += num;
    }
    double avg = sum/count;
  }
laune
  • 30,276
  • 3
  • 26
  • 40
  • Does that work around the `nextDouble` not consuming the linebreak issue? Wouldn't you have to call `nextLine`? – Boris the Spider Jan 11 '15 at 13:57
  • P.S. please use `try-with-resources` to clean up open files. – Boris the Spider Jan 11 '15 at 13:59
  • @BoristheSpider ? Works as advertised - you made me run a test – laune Jan 11 '15 at 14:01
  • Interesting, +1 to you! – Boris the Spider Jan 11 '15 at 14:02
  • @BoristheSpider I re-ran with more tests and once there seemed to be an error but I can't reproduce it (and I lost that shell where I did it). Any source for the issue you were referring to? – laune Jan 11 '15 at 14:13
  • There's [this](http://stackoverflow.com/a/13102066/2071828) and also [this](http://stackoverflow.com/a/26586629/2071828). Calling `nextInt` consumes the `int` and leaves a trailing newline character. I suppose the `Scanner` advances past the character on the subsequent call to `nextInt`. Seems you are right, not sure what your error was... – Boris the Spider Jan 11 '15 at 14:21
  • @BoristheSpider Default delimiter is "white space" which includes line ends. The problems in the links results from *mixing* nextLine with nextInt. – laune Jan 11 '15 at 14:25
0

I think this is what you were trying to do

public static void main(String[] args) {

    Scanner keyboard=new Scanner(System.in);

    System.out.println("Enter file name to be written");
    String file=keyboard.next();

    File fileName=new File(file);

    try{
        FileOutputStream fo=new FileOutputStream(fileName);
        ObjectOutputStream output=new ObjectOutputStream(fo);

        System.out.println("Enter numbers");
        System.out.println("enter q to quit");

        String number;

        do
        { 
            number=keyboard.next();
            if(number.equals("q")){
                output.writeUTF(number);
            }
            else{
                double new_number = Double.parseDouble(number);
                output.writeDouble(new_number);
            }   
        }
        while (!number.equals("q"));

        if(number.equals("q")){
            System.out.println("numbers were written to: "+fileName);
            output.close();
            fo.close();
        }
    }
    catch(FileNotFoundException e){
    }
    catch(IOException e){

    }

    double num=0;
    double num2=0;
    double num_check=0;
    double num3=Double.MAX_VALUE;
    int count=0;
    System.out.println("Now the program starts");

    try{
        FileInputStream fi=new FileInputStream(fileName);
        ObjectInputStream input=new ObjectInputStream(fi);
        double num_ave=0;
        long file_length=fileName.length();

        for(int i=0;i<file_length;i++){

            num=input.readDouble();
            if(num>=0){
            //System.out.println(num);
            num_ave+=num;
            }
            if(num>num_check){
                num_check=num;
            }
            if(num<num3){
                num3=num;
            }
            count++;

        //Here is my attempt at getting the average


        double average=num_ave/count;
        System.out.println(average);
        System.out.println("Average of all the numbers is: "+average);
        }
        input.close();
        fi.close();
    }

    catch(FileNotFoundException e){  
    }
    catch(EOFException e){

        System.out.println("Largest number: "+num_check);
        System.out.println("Smallest number: "+num3);

    }
    catch(IOException e){  
    }
}
Abhi
  • 331
  • 7
  • 14
-1

Its good practice to read the data from the file in bulk, close the file, then work with the data.

The file length is in bytes, not in doubles. Instead of using a counter, use while(input.hasNext())

If you can't use an array then use a LinkedList, or any iterable Collection. If that's not what you want then you could do something by sorting, though median may be difficult.

Khlorghaal
  • 222
  • 2
  • 11
  • It's in the question: _without using an array_. And, further, it is **rarely** good practice to read an entire file into memory before processing. In fact, I would argue that the exact opposite is true. – Boris the Spider Jan 11 '15 at 13:56
  • I think that if the OP cannot use an array, then they also cannot use a `List` or `Set` or `Queue` or any other collection - your answer is still wrong and now misses the point. – Boris the Spider Jan 11 '15 at 14:01