Reputation: 2070
I am trying to read a input of this format
4 4
* . . .
. . . .
. * . .
. . . .
4 4
* * . .
. . . .
. . . .
. . * .
I am able to read the first two numbers, when I try to read the symbols I get an exception. I can use BufferedReader to read each line and parse the input but why can't I do this with scanner?
This is my code
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextLine()) {
Scanner s = new Scanner(in.nextLine());
if (!s.hasNextLine())
break;
int x = s.nextInt(); // 4
int y = s.nextInt(); // 4
for (int i = 0; i <= x - 1; i++) {
for (int j = 0; j <= y - 1; j++) {
System.out.println(s.hasNext()); // false
String symbol = s.next(); //NoSuchElementException WHY?
}
}
}
}
}
Upvotes: 0
Views: 112
Reputation: 14478
You shouldn't try to read numbers when there aren't any numbers there.
Your loop, in pseudocode, looks like
While there is a line available:
s = NextLine()
x = FirstInt(s)
y = SecondInt(s)
// Some other stuff
When you assign to x
and y
, there is no number available except on the first line, so your application crashes.
A better solution, which matches the problem, would be
Scanner in = new Scanner(System.in);
if (!in.hasNextInt()) exitAndPrintError();
int rows = in.nextInt();
if (!in.hasNextInt()) exitAndPrintError();
int cols = in.nextInt();
for (int r = 0; r < rows; r++) {
for (int c = 0; c < cols; c++) {
if (!in.hasNext()) exitAndPrintError();
process(in.next());
}
}
This solution really doesn't check much for errors, leaving all error reporting to some exitAndPrintError
function that you would have to write.
As a side note: if you try s.hasNext()
and it returns false, then you should be surprised if s.next()
does not throw an exception. That's why the hasNext*
methods are available on Scanner
- they give you the chance to know when you have reached the end of the input, and not try to read any more input than is available.
I'll leave it as an exercise to update this code to handle multiple sets of data in a single file, but it isn't that difficult. The key bug in the code you posted is that, if you create a scanner s
using only a line from in
, you won't find a multi-line structure inside that single line that s
is processing.
Upvotes: 2
Reputation: 7821
Overall design problems withstanding, I will answer your question.
You get the NoSuchElementException
because, guess what, s
has no more elements. It becomes even more obvious with the output of s.hasNext()
which returns false.
The reason is simple. You assign s
with a single line of in
.
To fix the whole program, all you need to use is one scanner, and not multiple instances of it.
Upvotes: 1