Here are the contents of my input file (called input.txt)
C:\DIRECTORY_REMOVED>type input.txt
180
3
640 480
120 300
180 180
And here is the Java program I'm running it against (a friend wrote it),
import java.io.*;
import java.util.*;
class Square
{
public static void main (String args[]) throws IOException
{
BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
String s;
s = stdin.readLine();
int L = Integer.parseInt(s);
String m;
m = stdin.readLine();
int N = Integer.parseInt(m);
int a = 1;
while (a <= N)
{
Scanner sc = new Scanner(System.in);
int W = sc.nextInt();
int H = sc.nextInt();
if ( W < L || H < L)
{
System.out.println("UPLOAD ANOTHER");
}
else if ( W >= L && H >= L && W == H)
{
System.out.println("ACCEPTED");
}
else
{
System.out.println("CROP IT");
}
a++;
}
}
}
After compiling, if I were to manually enter the input on the command line, the program runs without issues (see below),
C:\DIRECTORY_REMOVED>java Square
180
3
640 480
CROP IT
120 300
UPLOAD ANOTHER
180 180
ACCEPTED
But if I attempt to redirect the input from the earlier text file an exception gets thrown,
C:\DIRECTORY_REMOVED>java Square < input.txt
Exception in thread "main" java.util.NoSuchElementException
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 Square.main(Square.java:18)
If the source code is re-written to use Scanner instead of BufferedReader for the initial input lines, the exception goes away. What I don't understand is WHY?
Does anyone have a good explanation of why the code runs perfectly fine if the data is entered manually from command prompt, but fails if redirected from a file?
The same behavior has been observed on Windows 7 (64-bit) and Windows 8.1 (64-bit). JDK used is also 64-bit (Java version 8).
OFF-TOPIC: The program was written in answer to a practice puzzle on HackerEarth - http://www.hackerearth.com/problem/algorithm/roy-and-profile-picture/
The standard console stream is line-buffered . That means that a system call to read some data will return once one line has been read, even if more input is available. This means that the BufferedReader
you wrap around System.in
just reads one line at a time to fill the internal buffer.
Then, when you wrap the Scanner
around System.in
, it can continue from where the BufferedReader
left off.
File streams are block-buffered . A system call will fill the entire supplied buffer if the file is large enough. Since your file is small, this means that the BufferedReader
will read the entire file in one go, and then supply data from its internal buffer, while the underlying stream sits at EOF.
This means that when you wrap the Scanner
around System.in
, all it sees is a stream already at EOF, from which it can't read anything.
Either wrap the Scanner
around your stdin
variable or use it from the beginning instead of the BufferedReader
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.