-3

I have program that is suppose to ask the user what txt file, go through the txt file and find all parsable ints and average them. I have the following code below, but it's giving me a bunch of errors. What is the cause of all these errors?

The txt file is: 5 15 312 16 eight seven 44 eighty-five thousand and sixty-two 13 98 93

import java.util.Scanner;


public class Ch12Pt2 {
public static void main(String[] args) throws NumberFormatException {
Scanner input = new Scanner(System.in);
System.out.print("Enter filename: ");
String filename = input.nextLine();
Scanner file = new Scanner(filename);

if(file.nextLine().equals(""))
{
    System.err.println("Could not find file:" + filename);
    System.exit(1);
}

do {
      try {
            int total = 0;
            int count = 0;
        int num = file.nextInt();
        total = num + total;

        //Display the results
        System.out.println("The number of parsable numbers: " + count);
        System.out.println("Average values: " + (total / count));




      } 
      catch (NumberFormatException ex) {
        System.out.println("Cannot parse " + num + " as an integer.");
        file.nextInt();
      }

    } while (file.hasNextInt());

// Close the files
input.close();
file.close();
   }
}

Exception in thread "main" java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at Ch12Pt2.main(Ch12Pt2.java:21)
  • 1
    `eight` is not a `int`, therefore `file.nextInt()` will fail – MadProgrammer Feb 04 '18 at 23:30
  • @MadProgrammer I would think NumberFormatException would take control of that. – jthecreator Feb 04 '18 at 23:38
  • 1
    `java.util.NoSuchElementException` doesn't extend from `NumberFormatException` or any common ancestor, so I wouldn't catch it – MadProgrammer Feb 04 '18 at 23:49
  • 1
    Also, `Scanner file = new Scanner(filename);` is not correct, this is passing the `String` `filename` to the `Scanner` to be processed, instead, you probably mean `Scanner file = new Scanner(new File(filename));` which will actually read the specified file – MadProgrammer Feb 04 '18 at 23:55

3 Answers3

1

If you look at the JavaDoc for the constructor you used, you will that it "Constructs a new Scanner that produces values scanned from the specified string." What you want is Scanner#Scanner(File source), "...a new Scanner that produces values scanned from the specified file".

Do not use do-while, it will through a null pointer if your file does not have any integers. Use while instead. Also, do not initialize any of your variables inside the loop. This will cause them to re-initialize at ever iteration.

What is the point of file.nextInt(); in your catch block? It causes the program to skip an extra integer. Remove it. Furthermore, do not call input.close();, you do not want to close System.in.

    @SuppressWarnings("resource")
    Scanner input = new Scanner(System.in);
    System.out.println("Enter filename: ");
    File file = new File(input.nextLine());

    /*
     * Check file existence before constructing your scanner. This will prevent a
     * FileNotFoundException. Notice, I used File#exists and the NOT operator '!'
     */
    if (!file.exists()) {
        System.err.println("Could not find file: " + file.getName());
        System.exit(0);
    }

    Scanner scanner = new Scanner(file);

    // Initialize variables outside of loop.
    int num = 0;
    int total = 0;
    int count = 1;
    // No do-while
    while (scanner.hasNextInt()) {
        try {
            num = scanner.nextInt();
            total += num;

            // Display the results
            System.out.println("The number of parsable numbers: " + count);
            System.out.println("Average values: " + (total / count));

            // count is pointless unless you increase it after every number.
            count++;
        } catch (NumberFormatException ex) {
            System.out.println("Cannot parse " + num + " as an integer.");
        }

    }

    // Close the files
    scanner.close();

Finally, as Mad Programmer pointed out, "eight seven" and "eighty-five thousand and sixty-two" are not numbers, thus Scanner#nextInt will not include them. A work around is to use Scanner#nextLine and parse accordingly. Something like this: How to convert words to a number?

Cardinal System
  • 2,749
  • 3
  • 21
  • 42
-1

Your code is all most all wrong. I have reworked it now it works.

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Scanner;


public class Ch12Pt2 {
    public static void main(String[] args) throws NumberFormatException, FileNotFoundException {
        Scanner input = new Scanner(System.in);
        System.out.print("Enter filename: ");
        String filename = input.nextLine();
        Scanner file = new Scanner(new FileReader(filename));
        int num =0;
        int count =0;
        int total =0;

        if(file.nextLine().equals(""))
        {
            System.err.println("Could not find file:" + filename);
            System.exit(1);
        }

        while (file.hasNextInt()){
            try {
                    num = file.nextInt();
                    total = num + total;
                   count++;


            }
            catch (NumberFormatException ex) {
                System.out.println("Cannot parse " + num + " as an integer.");
            }

        }

// Close the files
        input.close();
        file.close();
        System.out.println("The number of parsable numbers: " + count);
        System.out.println("Average values: " + (total / count));
    }

}
AliOmar62
  • 55
  • 2
  • 6
  • 1
    I can see you are new. here Let me give you some advice. ***Never*** just hand someone the code. Instead explain what mistake they made, why it is a mistake (if you can), and how exactly you fixed it. – Cardinal System Feb 04 '18 at 23:49
  • Got it. Thanks for the advise. Well everything in his code was wrong so tougth to help him. Still will remember it next time. – AliOmar62 Feb 04 '18 at 23:51
-1

Scanner file = new Scanner(filename);

Exception in thread "main" java.util.NoSuchElementException

If you're reading data from a text file using a Scanner you need to specify a File, not a string, which is why you're getting the above error.

Use:

Scanner scanner = new Scanner(new FileReader("foo.txt"));

And then recursively go through the text file like this:

while(scanner.hasNext())

Your code:

while (file.hasNextInt());

Will not work because the hasNextInt() method will stop processing the text file when it encounters anything other than an integer.

System.out.println("Cannot parse " + num + " as an integer.");

Variable num is defined in a different scope to the body that handles the exception. An additional error will be thrown because num is not defined within the NumberFormatException body.

The txt file is: 5 15 312 16 eight seven 44 eighty-five thousand and sixty-two 13 98 93

If the items in the text file are on the same line it would be better to use the split method to get all elements and then detect whether they're numbers or not.

String line = sc.nextLine();
String elements = line.split(" ");
for (String e : elements) {
 // add if int, or continue iteration
}

Otherwise, try something along the lines of:

int sum = 0;
int numElements = 0;
Scanner scanner = new Scanner(new FileReader("path-to-file"));
while (scanner.hasNext()) {
    try {
      int temp = Integer.parseInt(sc.nextLine());
      sum += temp;
      numElements += 1;
    }catch(NumberFormatException e) {
      continue;
    } 
}

System.out.println("Mean: "+ (sum/numElements));
Community
  • 1
  • 1
Lord Why
  • 14
  • 6
  • "...hasNextInt() method will stop processing the text file when it encounters anything other than an integer." This is actually not the case. It will return true if there are *any* integers left in the input. – Cardinal System Feb 04 '18 at 23:55
  • 1
    @CardinalSystem You should quote correctly. "Lord Why" included the `while` from OPs code in that sentence and he's right, it will stop processing/looping if the next token isn't an `int`. But your sentence "It will return true if there are any integers left in the input." is wrong. That method checks the next token, not any token left on the input stream. – Tom Feb 04 '18 at 23:59
  • Actually no, it will only return true if the next set of characters in the input stream can be read as of type int. According to the official Javadoc, "Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method." – Lord Why Feb 05 '18 at 00:09