James Gould
James Gould

Reputation: 4702

InputMismatchError when scanning from file

I'm trying to read data in from a .txt file into my program and it's throwing InputMismatchErrors despite it looking like it shouldn't.

The error

**********HELLO***********
Which animal are you looking to check into the kennel?: 
Dog
Cat
cat //typed entry
Using file cats.txt
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Unknown Source)
at java.util.Scanner.next(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at java.util.Scanner.nextInt(Unknown Source)
at KennelDemo.initialise(KennelDemo.java:82)
at KennelDemo.main(KennelDemo.java:337)

// The error occurs on this line:
infile.nextInt(); 
int feedsPerDay = infile.nextInt();

Here's the code snippet:

public class KennelDemo {
private String filename; // holds the name of the file
private Kennel kennel; // holds the kennel
private Scanner scan; // so we can read from keyboard
private String tempFileName;
private String dogsFile = "dogs.txt";
private String catsFile = "cats.txt";

/*
 * Notice how we can make this private, since we only call from main which
 * is in this class. We don't want this class to be used by any other class.
 */
private KennelDemo() {
    scan = new Scanner(System.in);
    boolean fileCorrect = false;
    do {

        System.out.print("Which animal are you looking to check into the kennel?: " + "\n");
        System.out.println("Dog");
        System.out.println("Cat");  
        tempFileName = scan.next();
        if(tempFileName.toLowerCase().equals("dog") || tempFileName.toLowerCase().equals("cat")) {
           filename = tempFileName.toLowerCase().equals("dog") ? dogsFile : catsFile;
           fileCorrect = true;
        }
        else {
          System.out.println("That is not a valid filename, please enter either 'Dog' or 'cat' in lowercase.");
        }
    }
        while(!fileCorrect);
}

/*
 * initialise() method runs from the main and reads from a file
 */
private void initialise() {
    kennel = new Kennel();

    System.out.println("Using file " + filename);

    // Using try-with-resource (see my slides from session 15)
    try(FileReader fr = new FileReader(filename);
        BufferedReader br = new BufferedReader(fr);
        Scanner infile = new Scanner(br)){

        String kennelName = infile.nextLine();
        int kennelSize = infile.nextInt();
        infile.nextLine();
        kennel.setCapacity(kennelSize);
        int numPets = infile.nextInt();
        infile.nextLine();
        kennel.setName(kennelName);
        for(int i=0; i < numPets; i++){
            String PetName = infile.nextLine();
            int numOwners = infile.nextInt();
            infile.nextLine();
            ArrayList<Owner> owners = new ArrayList<>();
            for(int oCount=0; oCount < numOwners; oCount++){
                String name = infile.nextLine();
                String phone = infile.nextLine();
                Owner owner = new Owner(name, phone);
                owners.add(owner);
            }
            //boolean mutualBoolean = infile.nextBoolean();
            infile.nextLine();
            String favFood = infile.nextLine();
            infile.nextInt(); 
            int feedsPerDay = infile.nextInt();

            Pet Pet = new Pet(PetName, owners, favFood, feedsPerDay);
            kennel.addPet(Pet);
        }

    } catch (FileNotFoundException e) {
        System.err.println("The file: " + " does not exist. Assuming first use and an empty file." +
                           " If this is not the first use then have you accidentally deleted the file?");
    } catch (IOException e) {
        System.err.println("An unexpected error occurred when trying to open the file " + filename);
        System.err.println(e.getMessage());
    }
}

and the .txt file (cats.txt)

DogsRUs
20
1
TestCat
1
TestOwner
12345
TestFood
3

I've been trying to figure this out for hours (had a problem with a boolean that I ended up just taking out of the program entirely because it was annoying the hell out of me) and I've made barely any progress. I've rewritten the .txt file several times to make sure that each piece of data corresponds with what's being read in next but it still throws an error.

Thanks in advance.

Upvotes: 0

Views: 62

Answers (1)

SamTebbs33
SamTebbs33

Reputation: 5647

When you call infile.nextLine(); after you add the owner to the list in the second for loop, you are skipping the favourite food line, which means that the next call to nextInt will come across a String, rather then a valid int. Remove this call to nextLine() and you should be ok.

//boolean mutualBoolean = infile.nextBoolean();
infile.nextLine();
String favFood = infile.nextLine();
infile.nextInt(); 
int feedsPerDay = infile.nextInt();

becomes

//boolean mutualBoolean = infile.nextBoolean();
String favFood = infile.nextLine();
int feedsPerDay = infile.nextInt();

In addition, you don't need to call infile.nextInt() after reading in the favourite food (see above code), as you will already be on the correct line.

Finally, all you need to declare a Scanner instance is the following:

Scanner infile = new Scanner(new File(filename));

Rather than

FileReader fr = new FileReader(filename);
BufferedReader br = new BufferedReader(fr);
Scanner infile = new Scanner(br)

Upvotes: 2

Related Questions