0

I have a text file (data.txt) with the following lines:

1   3   t1  a   b   c   d   1
2   1   t2  a   b   c   d   3

The values are separated by tabs and each line represents a new object. I'm reading data from the file and using it to create an object. I've been able to read the first 7 values, but when I reach the integer at the end, the scanner is unable to read it and I get an InputMisMatchException.

This is what I'm getting right now:

ID: 1
Category: 3
Title: t1
Option 1: a
Option 2: b
Option 3: c
Option 4: d
Exception in thread "main" java.util.InputMismatchException
    at java.base/java.util.Scanner.throwFor(Scanner.java:939)
    at java.base/java.util.Scanner.next(Scanner.java:1594)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2258)
    at java.base/java.util.Scanner.nextInt(Scanner.java:2212)
    at TestApp.readFile(TestApp.java:35)
    at TestApp.main(TestApp.java:9)

But I'm expecting something like this:

ID: 1
Category: 3
Title: t1
Option 1: a
Option 2: b
Option 3: c
Option 4: d
Result: 1
ID: 2
Category: 1
Title: t2
Option 1: a
Option 2: b
Option 3: c
Option 4: d
Result: 3

I have a Test class and a TestApp class to run the code

Test class:

import java.util.ArrayList;

public class Test {
    private int ID;
    private int category;
    private String title;
    private ArrayList<String> options;
    private int results;

    public Test(int ID, int category, String title, ArrayList<String> options, int result) {
        this.ID = ID;
        this.category = category;
        this.title = title;
        this.options = options;
        this.results = result;
    }
}

TestApp:

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

public class TestApp {
    public static void main(String[] args) {
        ArrayList<Test> tests = new ArrayList<>();
        readFile(tests, "data.txt");
    }

    public static void readFile(ArrayList<Test> tests, String inputFile) {
        File testFile = new File(inputFile);
        ArrayList<String> optionsList = new ArrayList<>();
        try {
            Scanner input = new Scanner(testFile);
            input.useDelimiter("[\t\n]");

            // Read data
            while(input.hasNext()) {
                int ID = input.nextInt();
                System.out.println("ID: " + ID);
                int category = input.nextInt();
                System.out.println("Category: " + category);
                String title = input.next();
                System.out.println("Title: " + title);
                String option1 = input.next();
                System.out.println("Option 1: " + option1);
                String option2 = input.next();
                System.out.println("Option 2: " + option2);
                String option3 = input.next();
                System.out.println("Option 3: " + option3);
                String option4 = input.next();
                System.out.println("Option 4: " + option4);
                int result = input.nextInt();
                System.out.println("Result: " + result);

                // Add to ArrayList
                optionsList.add(option1);
                optionsList.add(option2);
                optionsList.add(option3);
                optionsList.add(option4);

                // Create object
                Test newTest = new Test(ID, category, title, optionsList, result);
                // Add to test bank
                tests.add(newTest);
                // Clear ArrayList
                optionsList.clear();
            }
        } catch (FileNotFoundException error) {
            System.out.println("File not found");
        }
    }
}

I don't understand why the code fails at int result = input.nextInt(); when it was able to read the prior values. How can I fix this?

2
  • 3
    I bet you're on Windows, and that the text file uses \r\n as line terminators, and since you replaced the default delimiter of "\\p{javaWhitespace}+" with a simplified "[\t\n]" that doesn't handle \r\n pairs, or \r at all, the token seen is "1\r", which is not a valid integer value. Try useDelimiter("[\t\n]|\r\n") Commented Apr 15, 2021 at 21:53
  • 1
    Use try-with-resource for your Scanner, like this : try (Scanner input = new Scanner(testFile)) { to avoid memory leak. But in real world, use files JSON or XML with jackson, jaxb or Java built-in DOM parser. Commented Apr 15, 2021 at 22:21

1 Answer 1

1

What's giving you trouble is the useDelimiter() function.

I have tested the code and if you comment the line input.useDelimiter("[\t\n]"); it works fine and returns the correct output.

Sign up to request clarification or add additional context in comments.

1 Comment

Simply removing the useDelimiter() call is very likely not the right solution. OP likely added it for a reason, e.g. so input 1\t3\tt1\ta\t\t\td\t1 would correct be read as meaning that options 2 and 3 are empty strings, i.e. consecutive tab characters are treated as multiple delimiters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.