Java While loop not continuing to next statement - java

Sorry, should've added more
import java.util.Scanner;
public class rpg {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String input;
boolean live = true;
if (live == true){
System.out.println("DETECTIVE RPG");
while (true) { // << ENTER CHECK
System.out.print("\n Press Enter...");
input = keyboard.next();
if (input.equals(null))
break;
} // ENTER CHECK >>
System.out.print("Past check.");
keyboard is what I named the Scanner.
This prints "Press Enter" to the console and makes sure the input box is empty. If they press Enter it should break the While loop and move onto the next statement, right? When I press Enter it shows another input box and never gets to the next print statement.

There is no token to return yet from the Scanner when just "Enter" is hit. The next() method will block until it can read a token.
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern. This method may block while waiting for input to scan, even if a previous invocation of hasNext() returned true.
Switch to nextLine().
Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
Since this method continues to search through the input looking for a line separator, it may buffer all of the input searching for the line to skip if no line separators are present.
It will return the whole line of input. When the line is empty, it will return an empty string, "", not null. Try
input = keyboard.nextLine();
if ("".equals(input))
break;

Related

Inf While Loop when given incorrect input

Program overview: Ask user for phrase, ask user for an index in which a scramble will rotate the phrase until that letter at index is the first index (0) of the string. Ask for an Integer until an integer is given. After phrase is scrambled ask to scramble again. if yes, scramble to inputted index, if no, print final result end program.
Code:
import java.util.Scanner;
public class PJ {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String phrase;
String phraseMut;
int index = 0;
System.out.println("Enter your word or phrase: ");
phrase = scan.nextLine();
phraseMut = phrase;
System.out.println();
while (true) {
System.out.println("Enter an Integer: ");
if (scan.hasNextInt()) {
index = scan.nextInt();
scan.nextLine();
break;
} else if (index > phraseMut.length()) {
System.out.println("Error: Index is out of bounds.");
System.out.println("Please enter an integer value.");
} else {
System.out.println("Error: Index is not Integer.");
}
}
System.out.println();
System.out.println("Rotating phrase to bring index "+index+" to the front. . .");
int count =0;
for(int i = 0; i < index; i++){
phraseMut = phraseMut.substring(1,phrase.length())+""+phraseMut.substring(0,1);
count++;
System.out.println(phraseMut);
}
}
}
Issue: The while loop is running infinitely but what I need it to do is to check if its an integer, if it is, leave the loop and continue. If it's not an integer, keep asking for input until its an integer and same with if the integer is in the index range.
Scanner isn't actually designed for keyboard input, but you can use it for that. When you invoke hasNextInt(), and the next token is, say, "hello", then hasNextInt() does exactly what it says in its javadoc: It concludes the next token is not an int, and tells you so. That is it. It does not consume that "hello", so, if hasNextInt() returns false once, it will do so forever, at least, until you 'consume' the token.
Secondarily, you are expecting keyboard input to be separated out by single enter presses, but scanner isn't configured properly out of the box for that. You're badly hacking around it by invoking scan.nextLine() from time to time. This is bad; it means if the user ever touches the space bar (you know, the biggest key on the keyboard), all hell breaks loose as you're now out of sync on those nextlines, and it is also impossible to read blank input.
The fix for that is to tell the scanner you're using it for keyboard input - that you expect entries to be separated by enter keys. To do so, immediately after making the scanner, invoke .useDelimiter("\\R") (That's: A newline symbol, in regexp-ese). Then, never invoke .nextLine() - to read an entire line, invoke .next(). All inputs are entire lines (you hit 'enter' after entering a number just the same).
Thus:
Call .useDelimiter("\\R")
Delete all nextLine() calls you interject.
If you want an actual line, use .next(), not nextLine()
Consume the token if hasNextInt() returns false, by invoking .next() and ignoring its return value.

Java scanner - can't read user input

I want to read user input like: 11 12 13 14 15 16
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
System.out.println(sc.next());
}
System.out.println("Test");
but it newer goes out of while loop and prints "Test".
How could i read that input?
The method hasNext() works like this:
If it sees the end of the file, it returns false;
If it sees another valid, non-whitespace input, it returns true;
If neither of the above is true, it waits for the next input the user is going to enter, and doesn't return until he does.
Usually, if you use Scanner for files, such a loop will work correctly, because a file has a definite end, and it usually doesn't get stuck waiting for more input.
But when you are working with console input (System.in, not redirected), then usually the user does not send the end-of-file signal. He just presses Return, and so, hasNext() sits and waits to see if the user will enter more input on the next line and so on.
There are two general ways to deal with this:
The user has to actually terminate the input. After you finish entering all your numbers and press Return, you also need to send the end-of-file sequence, which is usually ctrlD or ctrlZ.
If you do that, you will not be able to enter any more input to that program.
The program tells the user to enter some particular value that will tell it that the input is over. For example, the string "DONE". When you do that, you have to change the loop to something like:
String nextInput;
while( sc.hasNext() && ! (nextInput = sc.next()).equals( "DONE" ) ){
System.out.println(nextInput);
}
You can break the loop depending whether you want to quit or not E.g.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String next = sc.next();
if (next.equals("q")) { //if user press q then break the loop
break;
}
System.out.println(next);
}
System.out.println("Test");
}
Use api like:
while(sc.hasNextInt()){
int aba= sc.nextInt();
if (aba == 0) {//or even non numeric value here would let this loop exit
break;
}
}
So you need to enter 0 or even in other way enter non numeric value inorder to come out of loop. nextLine method will read whole line just once and then you will need to parse it and then convert to integer so it's good to use sc.nextInt which will do the work for you.

Meaning of input.nextLine()

I am taking a course on Java and the "instructor" is introducing how to get the user's input. I don't understand what is the "input.nextLine()" for.
Here's the code:
import java.util.Scanner;
public class Application {
public static void main(String[] args) {
// Create Scanner object
Scanner input = new Scanner(System.in);
// Output the prompt
System.out.println("Type in something: ");
// Wait for the user to enter a line of text
String line = input.nextLine();
// Tell them what they entered
System.out.println("You just typed " + "'" + line + "'.");
}
}
It is for reading the next line from the input stream.
Scanner input = new Scanner(System.in);
// create a new reference and refer to the input stream.
String line = input.nextLine();
// read the next line from the stream (entered from the keyboard) and store it in a String variable named line
The java.util.Scanner.nextLine() method advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
It returns the next line, waiting if necessary for the line to become available (i.e. the user types out something and presses enter).

How to print characters as user inpt them in console and stop when user enters enter character java

I am trying to write a method that prints out whatever character the user is entering character by character appended with the previous ones as he enters and throws an exception when he presses enter. I have written the following code but when i enter, it appends what ever character I have written and does not throw an exception. I would appreciate your help and suggestion.
public static void inputM(StringBuffer a) throws EntExc, IOException{
char c;
String m;
while(true){
Scanner s = new Scanner(System.in);
m=s.next();
c=m.charAt(0);
if(c=='\r'){
throw new EntExc();
}
System.out.println(a.append(m));
}
}
There are a few issues here. First s.next() grabs a whitespace-delimited token and returns the entire token as a single string. Second, because Scanner uses whitespace as a delimiter, it will never return \r, it will just skip it and read the next token.
Why not use s.readLine() and simply echo the whole line? While it won't process characters as they are entered (Scanner can't really do this, it always buffers lines), it will be closer to your described requirement.

Not asking for input after the while loop starts again

My program is to enter a substring and return all the books based upon the search.i want to ask the user again to search again from the same records.The code is not asking for the user input for the second time.Kindly help
boolean runnable=true;
while(runnable)
{
System.out.println("\n\nInput Books you wish for search");
String search;
search=br.nextLine();
System.out.println("\n\nBooks by your search");
for(int i=0;i<noOfrecords;i++)
{
if(books[i].toLowerCase().contains(search.toLowerCase()))
{
System.out.println(books[i]);
}
}
System.out.println("\n\nMore Books");
for(int i=0;i<noOfrecords;i++)
{
if(!(books[i].toLowerCase().contains(search.toLowerCase())))
{
System.out.println(books[i]);
}
}
System.out.println("do you wish to search again from the same records?? (y/n)");
char searchagain=br.next().charAt(0);
if(searchagain!='y')
{
runnable=false;
}
else if(searchagain=='y')
{
runnable=true;
}
}
I am sure that you have an extra unconsumed new line character in your buffer. Consume it by adding a line at the end of the while loop after else-if
else if(searchagain=='y')
{
runnable=true;
}
br.nextLine();
When you hit enter after keying the first input, Scanner.nextLine() advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. so, the line seperator \n is still in the buffer, which is been consumed while iterating the loop for the second time.we need to consume it purposefully by invoking br.nextLine(); at the end of the while loop and leave the new line character \n in air and go for second loop for fresh input. This will make it to stop and get the input for the second time.
Let me explain you in a simple way. Your program asks for
Input Books you wish for search
Now, you give Effective Java and press enter. This would become
EffectiveJava\n
\n (unconsumed char) in the end of your input will not be consumed by br.nextLine(). So, we need to explicitly get rid of it at the end of while loop. so, that \n will not be consumed by the br.nextLine() during the second loop and it will ask for your input
Because you are not able to read single character from console - System.in because new bytes are available in stream after Enter key is pressed.
Can be useful:
http://sourceforge.net/projects/javacurses/
http://jline.sourceforge.net/
I made little changes in your code.
public void searchMethod(List<String> books){
Scanner scanner = new Scanner(System.in);
System.out.println("\n\nInput Books you wish for search");
//this code is executed when books is null, so first time you can invoke that method passing as argument simply null.
if(books == null){
while(scanner.hasNext())
books.add(scanner.nextLine());
}
System.out.println("\n\nBooks by your search");
for(String book : books)
{
if(book.toLowerCase().contains(search.toLowerCase()))
{
System.out.println(book);
}
}
System.out.println("\n\nMore Books");
for(String book:books)
{
if(!(book.toLowerCase().contains(search.toLowerCase())))
{
System.out.println(book);
}
}
System.out.println("do you wish to search again from the same records?? (y/n)");
char searchagain=scanner.nextLine();
if(!searchagain.equals("y"))
{
return;
}
else if(searchagain.equals("y"))
{
searchMethod(books);
}
}
}
change next().charAt(0) to nextLine().charAt(). it will work.i think reason for this is next() sperates the token by spaces and read the token one by one from the buffer and stay at the line. when next() reaches the end of line and if u call nextLine(), then nextLine() encounter the end of line and nextLine() return blank line.
char searchagain = br.next().charAt(0);
to
char searchagain = br.nextLine().charAt(0);

Categories

Resources