3

I'm new to Java and I'm trying to use a scanner to read in some data from a text file. The scanner reads in the string and integer data members fine, but when it reaches a double it throws an InputMismatchException.

The format of the text file looks like this...

Lastname,Firstname,0,0.0
Smith,John,10,2.456
Jones,William,15,3.568

Here is my code...

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

public class Student {

    int age;
    double gpa;
    String firstName;
    String lastName;

    public static void main (String[] args) {
        int iNum = 0;
        double dNum = 0.0;
        String str1 = "";
        String str2 = "";
        List<Student> listOfObjects = new ArrayList<>();

        try {
            Scanner src = new Scanner(new
                     File("data.txt")).useDelimiter(",|\r\n|\n");

            while (src.hasNext()) {
                str1 = src.next();  //last name
                str2 = src.next();  //first name
                iNum = src.nextInt();  //age
                dNum = src.nextDouble();  /* gpa - having trouble reading these doubles with Scanner */             

                Student object = new Student(str1, str2, iNum, dNum);
                listOfObjects.add(object); //add new object to list

            }
        } 
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        for (Student a: listOfObjects)   // printing the sorted list
            System.out.print(a.getStudentLastName() + ", " +  
            a.getStudentFirstName() +
            ", " + a.getStudentAge() + ", " + a.getStudentGpa() + "\n");
    }

    public Student(String str1, String str2, int iNum, double dNum){
        this.lastName = str1;
        this.firstName = str2;
        this.age = iNum;
        this.gpa = dNum;
    }

    public String getStudentFirstName() {
        return firstName;
    }

    public String getStudentLastName() {
        return lastName;
    }

    public int getStudentAge() {
        return age;
    }

    public double getStudentGpa() {
        return gpa;
    }

I tried setting the locale to US and tried messing with the delimiters, but nothing seems to be working.

  • @TimBiegeleisen I tried calling src.nextLine() after the call to src.nextDouble(), but the error is still being thrown. I also tried reading it in as a string and parsing to double, but the same error occurs. – Davis Smith Feb 06 '17 at 05:12
  • So the next element wasn't a double. – user207421 Feb 06 '17 at 08:55

2 Answers2

0

Big thanks to @Sotirios for calling out my incorrect closing of the question. Your problem is being caused by using an incorrect pattern in your scanner. Based on the snippet of the input file you showed us, there are spaces after each comma. Hence, you should be using the following pattern to reflect this:

,\\s*|\r\n|\n
^^^^^ match a comma, followed by zero or more spaces

When I tested locally, I didn't even get as far as the double value, it crashed when reading the third position integer. Try the following code:

Scanner src = new Scanner(new File("data.txt")).useDelimiter(",\\s*|\r\n|\n");
while (src.hasNext()) {
    str1 = src.next();
    str2 = src.next();
    iNum = src.nextInt();
    dNum = src.nextDouble();

    Student object = new Student(str1, str2, iNum, dNum);
    listOfObjects.add(object); //add new object to list
}

The reason the first two strings were getting through is that the space after the comma was being rolled up into the next string. But you don't get away with this with numbers, in which case the extra whitespace had nowhere to go and you ended up with the InputMismatchException you kept seeing.

Tim Biegeleisen
  • 387,723
  • 20
  • 200
  • 263
  • Sorry, I updated the post to show that there are no spaces after the commas. That was a typo on my part. I still tried this pattern anyways, to no avail. – Davis Smith Feb 06 '17 at 05:25
  • Then I can't reproduce your problem locally. You should work on making your problem reproducible so that others may try to solve it. – Tim Biegeleisen Feb 06 '17 at 05:26
  • How many lines of input can you read, or can you not even read a single complete line? – Tim Biegeleisen Feb 06 '17 at 05:28
  • It won't read even a single line. Though one odd thing that happens is that if I surround that nextDouble with an if statement, then it will catch that very last double in the file. All the rest of the doubles just remain at their initial 0.0. – Davis Smith Feb 06 '17 at 05:33
  • Could you make that file available online somehow, maybe through PasteBin or something similar? – Tim Biegeleisen Feb 06 '17 at 05:35
  • Strange, it works completely OK for me locally. I think you will have to step through your code line by line with a debugger. This should reveal the problem. – Tim Biegeleisen Feb 06 '17 at 05:48
  • I will do that. Thank you for taking the time to look at the issue. – Davis Smith Feb 06 '17 at 05:50
0

I resolved the issue. The delimiter pattern I was using looked like this (",|\r\n|\n"). So the scanner wasn't seeing a double, but instead was including it in the string with the last name separated by a carriage return.

The simple fix for this was to include a carriage return in the pattern.

The new pattern looks like this - (",|\r\n|\n|\r")