Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scanner delimiter not working as expectedwith input file (Java)

I am writing a program to read input from a text file that will always follow the format of char:int, such as the following:

A:3
B:1
C:2
D:2

(eof here)

I want to read in the characters and their corresponding numbers, ignoring the colons.

In my program I have the following declarations and initializations:

String fileName = "input.txt";
File file = new File(fileName);
Scanner in = new Scanner(file).useDelimiter(":");

Then, I try to read from my file using the following loop:

while(in.hasNextLine()){
        String t = in.next();
        int n = in.nextInt();
        ....
}

When I attempt to run my program in Eclipse, I receive the following error(s):

Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor(Scanner.java:864) 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 Huffman_Encoder.main(Huffman_Encoder.java:26)

i.e., the line: int n = in.nextInt(); is throwing an exception. I am not sure why this is the case. From my understanding of Scanner delimiters, I should be skipping over the colons and so int n = in.nextInt(); should put the value following the colon into n.

What am I not seeing here?

OS is Windows 10, if that matters. Thank you.

edit: upon further testing, I've pinpointed the error as occurring immediately after String t = in.next(); Printing out t immediately after this shows 'A', and then the program throws its exception at int n = in.nextInt();

like image 994
MV94 Avatar asked Sep 26 '26 18:09

MV94


2 Answers

The actual input that the scanner gets is this string:

A:3\nB:1\nC:2\nD:2

So the quick fix is to add \n to the list of delimiters:

Scanner in = new Scanner(file).useDelimiter("[:\n]");

However, this is probably not strictly correct, as this would accept any stream with colons or newlines between the letters and numbers, e.g.:

A
3:B
4

So you'd be better off reading the input line by line and splitting at the colon (see String.split()).

like image 70
dovetalk Avatar answered Sep 28 '26 07:09

dovetalk


Before accessing Scanner.next**() methods be advised to use the appropriate Scanner.hasNext**() methods. If you expect an integer then check the next token with Scanner.hasNextInt() and get it by Scanner.nextInt().

Here you have checked the next token with Scanner.hasNextLine() which says that there at least one more line in the input. But you are trying to access the next token with Scanner.next() and then Scanner.nextInt().

like image 37
Kamil Akhuseyinoglu Avatar answered Sep 28 '26 07:09

Kamil Akhuseyinoglu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!