0

I have file with the below data

A,8,43
B,7,42,
C,9,34

I am using the below code to read the data

Scanner input = new Scanner(new File("D:\\test.txt"));
input.useDelimiter(",|\n");  
while(input.hasNext()) {
   String name = input.next();
   int age = input.nextInt();
   int height = input.nextInt();

When I am executing the program I am getting InputMisMatch exception, Please suggest what is mistake.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
user7076183
  • 43
  • 1
  • 2
  • 11
  • Use more than one Scanner -- the first using a while loop to read **lines** from the File using `hasNextLine` and `nextLine`, the second within the while loop, using the line String obtained to extract tokens from the line. Match each `hasNextXxx` with a `nextXxx`. – Hovercraft Full Of Eels Jun 17 '17 at 16:28

3 Answers3

2

At end of second line you have , and line separator (I am assuming \n) This means you have empty element between these two delimiters.

So in third iteration

String name = input.next();  
int age = input.nextInt();
int height = input.nextInt();

input.next(); is consuming "", which means input.nextInt() will try to consume C.

To solve this problem you can set delimiter to be combination of one or more commas and line separators like

input.useDelimiter("(,|\n)+");

To improve your code even farther instead of \n you can use \\R added in Java 8 (or \r|\n in earlier versions) to handle all line separators, because currently you don't consider \r as delimiter so it can be treated as valid token.

So better solution would be using

input.useDelimiter("(,|\\R)+"); //for readability

or even

input.useDelimiter("[,\r\n]+");
Pshemo
  • 122,468
  • 25
  • 185
  • 269
2

The problem lies at the use of the useDelimiter method. This method accepts a regular expression as a parameter. You can't just say ,|\n to mean "comma or new line". There are rules.

What you should pass in is "[,\\n]+". This means "one or more characters in the following set: [comma, new line character]".

With the regex that you are passing currently, ,|\n, it means that the delimiter should be either , or \n, but not both. So when it encounters the second line:

B,7,42,

this is what happens:

  • next reads "B"
  • nextInt reads "7"
  • nextInt reads "42"
  • next reads an empty string that is between the "," and the new line.
  • nextInt now tries to read the next token "C", which it can't.
  • EXCEPTION!
Sweeper
  • 213,210
  • 22
  • 193
  • 313
1

I would do things differently -- use one Scanner to parse each line of the File and use a 2nd Scanner nested within the while loop to extract tokens or data from the lines obtained from the first Scanner. For example:

String filePath = "D:\\test.txt";
File file = new File(filePath);

// use try-with-resources
try (Scanner input = new Scanner(file)) {
    while (input.hasNextLine()) {
        String line = input.nextLine();
        Scanner lineScanner = new Scanner(line);
        lineScanner.useDelimiter("\\s*,\\s*"); // get comma and any surrounding whitespace if present
        String name = "";
        int age = 0;
        int height = 0;
        if (lineScanner.hasNext()) {
            name = lineScanner.next();
        } // else ... throw exception?
        if (lineScanner.hasNextInt()) {
            age = lineScanner.nextInt();
        } // else ... throw exception?
        if (lineScanner.hasNextInt()) {
            height = lineScanner.nextInt();
        } // else ... throw exception?

        // use name, age, height here
        System.out.printf("%s %s %s%n", name, age, height);

        lineScanner.close(); // don't waste resources -- return them
    }
} catch (IOException e) {
    e.printStackTrace();
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373