How is the while loop condition re-evaluated again - java

I've came across the below code snippet
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
boolean flag = scan.hasNext();
while(flag){
System.out.println(scan.nextLine());
}
System.out.println("End");
}
}
The boolean flag once assigned the value true or false should not be changed again, but I see that whenever I type something in the terminal the while loop is executed again.
Can someone please explain how the flag is re-evaluated again whenever I type something in the terminal?
Note: My question is not about stopping/closing the Scanner, but its about understanding how the loop condition is re-evaluated.

I think that what you are experiencing here is scan.hasNext() blocking until your first input.
Then, the flag is always true.
Once in the loop, you print the next line, but scan.nextLine() also blocks until you provide an EOL, i.e., an input with a line end.

Related

Why is the following code showing twice the statements inside try block inside the loop?

Following is the program for reversing a word using a stack. There is no problem in implementation of stack. It is executing finely. When ctrl-c is pressed, it prints the content of try-catch block twice or even thrice. What causes this?
import java.util.NoSuchElementException;
import java.util.Scanner;
class WordReversal {
public static void main(String args[]) {
StackIFace sfWord; // interface reference
Stack s = new Stack();
sfWord = s;
Scanner sc = new Scanner(System.in);
System.out.println("Control-C to stop.");
for(;;) {
String senWord = "", revWord = "";
try {
System.out.println("Enter a word: ");
senWord = sc.next();
for(int i=0;i<senWord.length();i++)
sfWord.push(senWord.charAt(i));
for(int i=0;i<senWord.length();i++)
revWord+=sfWord.pop();
System.out.println("Original Word::"+senWord+"\nReversed Word::"+revWord);
} catch(NoSuchElementException NSEe) {
System.out.println("Control-C command accepted.\nQuitting...");
//break;
}
}
}
}
One thing to notice here is if I put break (just remove two forward slashes in above code), the problem is solved but exactly what is causing this? Is Scanner causing this or is it a language problem?
NoSuchElementException is not actually "intercepting ctrl/C". So what's likely happening is you're terminating input, the next() call throws an exception because there is no input, you print a message, and loop round to do it again.
Input is still terminated, so the next() call throws an exception....
What surprises me is thus not that it loops, but that it stops looping after 2 or 3 times. Maybe some other exception gets thrown that you don't catch; hard to say without adding a handler to check.
But the root issue is: if you want that particular exception to quit the program, you need to write code that quits the program. You in fact did that when you wrote the 'break' out of the loop.
You're using an infinite for loop and not telling it when to stop.
Adding break statement is terminating the for loop. Hence, it is working.

hasNextLine() always returning true within While Loop

This question is linked to a previous question I asked regarding the same program, which can be viewed here:
Writing to a file code causing an endless loop
I have fixed the problem above and rewritten the function as a while loop rather than do while, but now I have the opposite problem that nothing is being written to the file. I've inserting a print statement to tell me the status of hasNextLine, and it is always returning as true even when a blank line has been entered, which is when I want the writer to terminate.
Here is the updated code:
import java.util.Scanner;
import java.io.FileNotFoundException;
import java.io.PrintWriter;;
public class Lab_Week8_WriteAStory {
public static void main(String[] args) throws FileNotFoundException {
Scanner whatToWrite = new Scanner (System.in);
PrintWriter writing = new PrintWriter ("Read and Write Files/output.txt");
while (whatToWrite.hasNextLine()){
String writeToFile = whatToWrite.nextLine();
writing.println(writeToFile);
System.out.println (whatToWrite.hasNextLine());
}
writing.close();
whatToWrite.close();
}
}
Check the documentation for Scanner.hasNextLine():
Returns true if there is another line in the input of this scanner. This method may block while waiting for input. The scanner does not advance past any input.
This is what's happening. Since you are using System.in as input source, the method is waiting for your input and once you provide it, it returns true and proceed to the next line and the process repeats itself.

Loop condition hasNext(), hasNextLine(), hasNextInt() and End of File

I have to write a programme that takes in a word, and 2 integers. The programme should stop when it reaches End Of File.
The following is my initial code:
import java.util.*;
public class Test {
public static void main(String[] args) {
String str;
int x, y;
Scanner scan = new Scanner(System.in);
while (!scan.hasNextInt()) {
str = scan.next();
x = scan.nextInt();
y = scan.nextInt();
}
}
}
But I got an error. I change the while condition to scan.hasNextLine(), and it still didn't work. Eventually, I change the condition to scan.hasNext(), and it worked. Why?
If you read the documentation of Scanner you will find:
public boolean hasNext()
Returns true if this scanner has another
token in its input.
If you want to use hasNextLine(), you need to read a line in every loop then parse it to a String and two ints, otherwise you need to check for the availability of the next token then read it. In which a token can be an int or a String in your case via using the above-mentioned public boolean hasNext() method.
On the other hand, hasNextInt() is checking for the existence of the next int without checking for the next String, thus the condition logic in your while-loop is not appropriate in your program.

How to terminate while loop once response is correct?

I'm working on this program that says "get some ice cream"/"put on a jacket" if you type "hot/cold". However, even after you type in hot/cold, the program keeps going in the while loop. How can I make this program keep asking the user for their condition until they correctly respond with one of the two answers, and prevent it from continuously asking for a response even after the user types a correct answer?
import java.util.Scanner;
public class IfStatement {
public static void main(String[] args) {
boolean run = true;
while(run) {
System.out.println("What is your condition: ");
Scanner input = new Scanner(System.in);
String x = input.nextLine();
if(x.equals("hot"))
System.out.println("Get some ice cream");
else if(x.equals("cold"))
System.out.println("Put on a jacket");
else
System.out.print("Try again, what is your condition: ");
}
}
}
your loop iterates as long as run is true. what you need to do is therefore to set run to be false once the input is correct. like this
if(x.equals("hot")){
System.out.println("Get some ice cream");
run = false; // setting run to false to break the loop
}
else if(x.equals("cold")) {
System.out.println("Put on a jacket");
run = false; // setting run to false to break the loop
}
break statement can be used as well.
You may also use do while loop.
In this case, you would have the ability to check your condition against "x" when the loop ends, and hence would not need additional flag.
However, do while loop will run at least once, which I assume you need as per your requirement.

While Loop executing one last time when condition is set to false

Task: To check that if a user input string has the same first and last character. If yes or no, output to the screen, if the user enters "done", the loop is exited.
Issue: While loop executes when condition is false
What I've tried: Using different types of loops, doing a loop within the loop to revalidate the code and all together giving up!
import java.util.*;
public class lab_15 {
public static void main(String args[]) {
String userInput = "";
String done = "done";
while (!userInput.equalsIgnoreCase(done))
{
int length;
Scanner sc = new Scanner(System.in);
userInput = sc.next();
length = (int)userInput.length();
if (userInput.charAt(0) == userInput.charAt(userInput.length()-1)) {
System.out.println("The first character equals the second character.");
}
else {
System.out.println("The first and second characters are different.");
}
}
// EXIT LOOP
System.out.println("Thank you for using this software!");
}
}
Inputs
+ bradley
+ hannah
+ done
I am still new to the site and have referred to the t's & c's regarding posts. Please do not negative if you find the question to not be challenging. I am new to programming and hope to progress.
Thank you!!!
This is because you change your userInput immediately once entering the loop. The condition is only checked when you reach the top of the loop, so if you invalidate the condition halfway through, it will continue executing until you reach the top.
The solution is to refactor so that the very last thing that happens is changing your userInput so that the condition is check immediately after the value is changed. (I would also pull the scanner instantiation out of the loop.)
Alternatively you could check your condition inside of the while loop and call break if the userInput has changed to match the terminating condition. The break keyword will force the logic to exit the loop immediately, without evaluating the condition again.

Categories