Not asking for input after the while loop starts again - java

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);

Related

How to ask user for ONLY one word string input and produce error prompt in a try-catch block

EDIT: I figured it out! I got rid of the try-catch block because it just didn't work the way I wanted it to. The code below is my final one. Thank you to everyone who responded to this question.
I am trying to code a to-do list program. One function of this program is to search for the entries inside the string array. The user should only input a ONE WORD keyword so if the user inputs more than one word or none, a prompt should show telling the user to try again. The code I've written so far is inside a try-catch statement. Using next() scanner only takes the first word and disregards the rest when inputting a multiple-word keyword, instead of producing an Exception. Here is my code for it:
case 2:
String searchKeyword;
int success = 0;
while(success==0) {
System.out.print(">> Enter 1 keyword: ");
searchKeyword = sc.nextLine();
String splitSearchKeyword[] = searchKeyword.split(" ");
if (splitSearchKeyword.length == 1) {
if(Quinones_Exer2.searchToDoList(searchKeyword, todoList)==-1) {
System.out.println(">> No item found with that keyword!");
System.out.println();
}
else {
System.out.println(">> Found one item!");
System.out.println("("+(Quinones_Exer2.searchToDoList(searchKeyword, todoList)+1)+")"+" "+todoList[Quinones_Exer2.searchToDoList(searchKeyword, todoList)]);
System.out.println();
}
success++;
}
else {
System.out.println(">> Please input a single word keyword!");
System.out.println();
}
}
break;
}```
Use Scanner.nextLine() then split the supplied string. If the length of array is greater than 1 or the supplied string is empty then issue an invalid entry message and have the User enter the string over again:
while(tries2 == 0) {
searchKeyword = "";
while (searchKeyword.isEmpty()) {
System.out.println("Enter 1 keyword: ");
searchKeyword = sc.nextLine().trim();
if (searchKeyword.isEmpty() || searchKeyword.split("\\s+").length > 1) {
System.out.println("Invalid Entry! {" + searchKeyword
+ "You must supply a single Key Word!");
searchKeyword = "";
}
}
tries2++;
// ... The rest of your code ...
}
From the docs of Scanner.next():
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern.
You would need to call next() again to get the the rest of the input.
Much simpler would be to use Scanner.nextLine() to get entire line and then use String.split() with whatever delimiter you are using to get an array of all inputted keywords.
Edit: Scanner.next(pattern) may do what you are looking for. It throws InputMismatchException if the input does not match provided pattern(regex). Example:
scanner.next("^[a-zA-Z]+$")
This requires the entire line to consist of lower and/or upper case letters and nothing else.

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.

Trying to use scanner in java to read just a stroke of the return key as an input?

I am making a program that will read user input and determine with an if/else condition what to do. If the user hits just enter and doesn't type anything else in, I want to loop something through the if. If anything else is typed as an input, the program should exit back to a different menu.
Here is what I have so far:
Scanner scnr = new Scanner(System.in);
String choice = scnr.next();
if (choice.equals("")) {
...
}
else {
...
}
When I run through it, just pressing enter does not affect anything, it just makes the cursor advance to the next line in the console. However, when I type something in, the error part that sends it to the menu when anything else is typed in works just fine. I'm thinking I have to use something besides scnr.next(); but I don't know what that would be.
This is for an entry level class, and it requires that we use the scanner utility and not something more advanced. Thanks in advance.
do
{
//string variable used to take scanner input when
//looping generations
String choice = "";
printWorld( patternName, world, generationCounter);
System.out.println("Options");
System.out.println("(Enter): show next generation");
System.out.println("end(Enter): end this simulation");
System.out.print("Choice:");
choice = scnr.nextLine();
if (choice.length() == 0) {
//used as a filler array when the method
//next generation is called
boolean newWorld[][] = new boolean [world.length][world[0].length];
nextGeneration(world, newWorld);
for (int i=0; i<newWorld.length;i++){
for (int j = 0; j<newWorld[0].length; j++){
world [i][j] = newWorld[i][j];
}
}
generationCounter++;
System.out.println("went through");
} else {
generationKill = 1;
generationCounter = 1;
}
} while (generationKill !=1);
Try using scnr.nextLine(); instead of scnr.next();
The reason for this is because of tokens. next()'s documentation says:
public String next()
Finds and returns the next complete token from this scanner.
Token generally is separated by whitespaces ("\n", "\t", " ") and therefore will not recognize your "enter" or "\n" character as a token. Which is why it'll keep reading, thinking that you haven't entered any tokens.
nextLine() on the other hand will read until it finds a "\n" character. That means when you enter, it's reading in a "\n" character, thereby setting your choice to be "".

Java While loop not continuing to next statement

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;

Reading Strings next() and nextLine() Java

The problem is I cant read the variable input with next() cause when I try to split (.split" ") every whitespace then the array just get the first two words I type so I had to use keyboard.nextLine() and the splitting process works the way it should work and I get all the words in the array but the problem is that If I use nextLine() then I have to create another keyboard object to read the first variable (answer) and that is the only way I can make it work here is the code
Scanner keyboard=new Scanner(System.in);
Scanner keyboard2=new Scanner(System.in);//just to make answer word
int answer=keyboard.nextInt();//if I don't use the keyboard2 here then the program will not work as it should work, but if I use next() instead of nextLine down there this will not be a problem but then the splitting part is a problem(this variable counts number of lines the program will have).
int current=1;
int left=0,right=0,forward=0,back=0;
for(int count=0;count<answer;count++,current++)
{
String input=keyboard.nextLine();
String array[]=input.split(" ");
for (int counter=0;counter<array.length;counter++)
{
if (array[counter].equalsIgnoreCase("left"))
{
left++;
}
else if (array[counter].equalsIgnoreCase("right"))
{
right++;
}
else if (array[counter].equalsIgnoreCase("forward"))
{
forward++;
}
else if (array[counter].equalsIgnoreCase("back"))
{
back++;
}
}
}
}
Thanks :)
Put keyboard.nextLine() after this line:
int answer=keyboard.nextInt();
This is a common problem that usually happens when you use nextLine() method after nextInt() method of Scanner class.
What actually happens is that when the user enters an integer at int answer = keyboard.nextInt();, the scanner will take the digits only and leave the new-line character \n. So you need to do a trick by calling keyboard.nextLine(); just to discard that new-line character and then you can call String input = keyboard.nextLine(); without any problem.

Categories

Resources