Scanner.hasNext() not working properly when running in Eclipse - java

I wrote a simple program to loop and find max of a set of numbers input by the user as:
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int currMax, currEl;
currMax = sc.nextInt();
while (sc.hasNext()) {
currEl = sc.nextInt();
currMax = (currEl > currMax ? currEl : currMax);
}
sc.close();
System.out.println(currMax);
} // end function main
}
I am using Eclipse on Windows.
When I run it the first time it runs fine, and considers Ctrl-Z as EOF and exits the loop. But second time onwards, it does not seem to read the EOF. I am unable to explain this, or fix this behavior.. what do you think is going on, and how do I fix it??
Follow-up: The problem happens with Eclipse, and not when I use cmd line. I suspect this is what is happening -- if I use cmd line, I can do Ctrl-Z and then hit Enter, but if I use Eclipse, I believe as soon as I hit Ctrl-Z, s.hasNext() evaluates to false and the above program terminates.

Related

Code after while loop never executes

Obviously, my real code is more complex, but here's an example:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in).useDelimiter("\n");
String[] cmdSplit = null;
while (true) {
while (input.hasNext()) {
cmdSplit = input.next().split("\\s+");
System.out.println("stuff");
}
for (int i = 0; i < cmdSplit.length; i++) System.out.println(cmdSplit[i]);
}
}
}
In the above example, the code takes input from System.in, splits it, and should output each piece. However, for some reason, the code after the inner while loop never executes. If I replace while with if, it works. If you test it, you can see it doesn't run infinitely, because it only prints "stuff" once, showing the loop runs once. What is the issue with the while loop?
Reading from System.in is different than reading from a file or other fixed-size source of input. The input doesn't necessarily exist until you create it, and so attempts to read it need to block until the input actually arrives (i.e. you type it). Try typing another line - you'll see the stuff message again; that will allow .hasNext() to return because there is now input.
To have .hasNext() return false the input source needs to be closed. For a command line application you can do this by sending the EOF signal (Ctrl+D on Linux) which tells the process stdin has no more input. That's not generally how you want a program to work, though, so if your intent is to only read one line and then move on, you should in fact be using an if instead of a while as you've tried to do. Later if you need to read more input you'll call .hasNext() again and your program will block there until the user passes more input.
As #user7 mentions your outer while (true) combined with while(input.hasNext()) is redundant. If you want to read only once get rid of the while (true) and use if (input.hasNext()). Otherwise if you want to read forever just combine the two loops:
while (input.hasNext()) {
cmdSplit = input.next().split("\\s+");
System.out.println("stuff");
for (int i = 0; i < cmdSplit.length; i++) System.out.println(cmdSplit[i]);
} // Loop will terminate once stdin is closed, e.g. by the user sending EOF.
Yes , your code won't go to the for loop because the Scanner.hasNext() will always listen to the console for inputs.
You have to break the loop in order to come out and go to the for loop.
Scanner input = new Scanner(System.in).useDelimiter("\n");
String[] cmdSplit = null;
while (true) {
while (input.hasNext()) {
cmdSplit = input.next().split("\\s+");
System.out.println("stuff");
break;
}
for (String element : cmdSplit) {
System.out.println(element);
}
}
The reason it is printing "stuff" only one time is because the hasNext() returned false.
Let me explain what I have observed.
To get "stuff" printed indefinately the assignment has to be removed. meaning once you assigned the input the scanner does not have any more token
The java.util.Scanner.hasNext() method Returns true if this scanner has another token in its input.
This will print indefinitely
while (input.hasNext()) {
// cmdSplit = input.next().split("\\s+");
System.out.println("stuff");
}

Trouble With hasNext() in Java

I'm trying to write a program that reads pairs of words and outputs the number of pairs of identical words. It's assumed an even number of words are inputted. When I run my code, it doesn't output anything. It appears to be continually running. When I press Ctrl-Z after I'm done inputting words, it either returns "0" or nothing at all. Any thoughts on how to make my program run properly? Thanks.
EDIT: it runs fine in the command prompt, but not in Eclipse.
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int counter = 0;
while (input.hasNext()) {
String string1, string2;
string1 = input.next();
string2 = input.next();
if (string1.equals(string2)) {
++counter;
}
}
System.out.println(counter);
}
You are asking hasNext() once, but then calling next() twice. The second next() can fail if there are no more elements.
It doesn't really work in eclipse for me (nor does in netbeans for what i have read), to test if your code actually works well you should do this:
(In windows) Open a command prompt ( execute ... "cmd" + Enter )
then compile your class or classes with
javac YourClass.java
if no errores it will just let you type a new command with no messages and then
java YourClass
then you can try the Ctrl + z in windows (ctrl + d in linux) which will print the ^Z character and then hit enter.
Hope it helped.

My console is flashing - Java - Eclipse

When I am running a simple java program in eclipse, when I run it, the console flashes what it should, then it disappears.
public class apples {
public static void main(String[] args) {
int age = 60;
if (age < 50) {
System.out.println("You are young");
} else {
System.out.println("You are old");
}
}
}
Your program is immediately terminating after printing what needed to be printed. You can use several methods to keep the console on the screen.
Your program is immediately terminating after printing what needed to be printed. You can use several methods to keep the console on the screen. One possibility is to use
while(true);
to stop the application from exiting. Beware that you should only use this for debugging methods!
Another, probably better, way is to ask for input before closing the window.
Simply read a line from standard input. Your program will wait until you type something and only then exit.
Scanner sc = new Scanner(System.in); // create a scanner that will read from standard input
String s = sc.nextLine(); // You don't even need to save the return value of
// sc.nextLine() here

why my program never reach the solve method?

sorry if its a stupid question, but I a beginner using StreamTokenizer, I am trying to solve this exercise this, please help me, I dont know what its wrong in my program that never reach my solve method, it also never finishes, I already ask in timus forum, but I know that here is faster to receive an answers
import java.io.*;
public class Prueba {
static int index = 0;
static double[] l = new double[131072];
public static void main(String args[]) throws IOException {
StreamTokenizer str = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
while (((str.nextToken() != StreamTokenizer.TT_EOF))) {
if (str.ttype == StreamTokenizer.TT_NUMBER) {
l[index++] = str.nval;
//System.out.println(str.nval);
// System.out.println(l[0]);
// System.out.println(l[1]);
}
}
solve();
}
public static void solve() {
double res;
for (int i = index - 1; i >= 0; i--) {
res = Math.sqrt(l[i]);
System.out.println(String.format("%.4f\n", res));
}
}
}
You are reading from the standard input, and your code loops until it gets a TT_EOF. To feed a TT_EOF into your program, you need to press Ctrl-D if you're using Unix, or Ctrl-Z followed by Enter if you're using Windows.
You are waiting on System.in, it is blocking on read, ergo, you will never get to EOF so you while loop will continue to wait for input.
As it is, you either need to pipe a file from command line, or enter text on console followed by EOF character. Pressing Ctrl+Z generates EOF in Windows, and pressing Ctrl+D generates EOF in Unix/Linux.
EDIT: If your input is single line you can check for TT_EOL instead of TT_EOF.
You must call eolIsSignificant(true) before entering the loop. This will make sure end-of-line is treated as separate token

why's this program giving a runtime error on jcreator but not on netbeans?

This is my solution for sphere's online judge palin problem. It runs fine on Netbeans, but the judge is rejecting my answer saying it gives a RuntimeError. I tried it on JCreator and it says:
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:468)
at java.lang.Integer.parseInt(Integer.java:497)
at Main.main(Main.java:73)
I'm not passing an empty string for it to parse, why is this?
The code:
import java.io.*;
import java.util.*;
class Main {
public static int firstPalinLargerThanNum(int num){
int foundPalin =0;
int evalThisNum = ++num;
while (true){
if (isPalin(evalThisNum))
break;
evalThisNum++;
}
foundPalin = evalThisNum;
return foundPalin;
}
public static boolean isPalin(int evalThisNum){
boolean isItPalin = false;
int dig=0;
int rev=0;
int n = evalThisNum;
while (evalThisNum > 0)
{
dig = evalThisNum % 10;
rev = rev * 10 + dig;
evalThisNum = evalThisNum / 10;
}
if (n == rev) {
isItPalin=true;
}
return isItPalin;
}
public static void main(String args[]) throws java.lang.Exception{
BufferedReader r1 = new BufferedReader(new InputStreamReader(System.in));
/*BufferedReader r1 = new BufferedReader (new FileReader(new File ("C:\\Documents and Settings\\Administrator\\My Documents\\NetBeansProjects\\Sphere\\src\\sphere\\sphere\\PALIN_INPUT.txt")));*/
String read = r1.readLine();
int numberOfTestCases = Integer.parseInt(read);
for (int i=0; i<numberOfTestCases;i++){
read = r1.readLine();
if (read!=null){
int num = Integer.parseInt(read);
System.out.println(firstPalinLargerThanNum(num));
}
}
}
}
Input:
2
808
2133
line 73 is: int num = Integer.parseInt(read);
You will get that error if you hit <Enter> when the program is expecting a number.
Suppose your input is
2
3
<Enter>
You will receive the error you have indicated after processing the number 3, as you have told your routine to iterate twice.
As an aside, on top of error handling around the number parsing, you might also want to introduce a trim() to the readLine() method calls:
String read = r1.readLine().trim();
This will allow you to handle gracefully the input in the event that the user to put in whitespace around the numbers.
Just a wild guess: Could there be a problem with different end-of-line separators.
E.g. your program actually gets 2<CR><LF>808<CR><LF>2133<CR><LF>, thinks that the line ends at the <CR> and processes the line.
Now when it tries to process the next line it finds <LF> which makes it think it read an empty String.
You cannot assume that the user knows how to use your program and will give you correct input. The judge probably hit enter, without typing any number. How is he/she supposed to know the input that your program requires? A program should fail gracefully, not blow up in the user's face with cryptic errors.
You should be doing something like the following, so that the user knows what to do:
private static function readInt(BufferedReader reader) throws IOException
{
boolean done = false;
int result = -1;
while ( ! done ){
System.out.print("Please enter an integer: ");
String str = reader.readLine();
try{
result = Integer.parseInt(str);
done = true;
}catch(NumberFormatException cantconvert){
System.out.println("That isn't an integer. Try again.");
}
}
return result;
}
Additionally, you shouldn't use an exception specifier with the main function (that is, don't use "throws" in the signature of "main"). You should handle those IOExceptions and print a pretty and intelligible message to the user, even if there is nothing you can do about the exception to fix it or make it go away.
I just ran your example code under Eclipse 3.4 without error. I was only able to induce a similar error when I did not provide the specified number of test cases, i.e.:
6
56
87
[Enter]
So I am inclined to agree with akf that there must be an extra Enter happening somewhere, because this error will only be generated when there are insufficient lines of input.

Categories

Resources