What am I doing wrong with this scanner? [duplicate] - java

This question already exists:
Scanner issue when using nextLine after nextXXX [duplicate]
Closed 8 years ago.
This is my current code, fairly basic, I'm adding names to an array and deleting said names using scanners. Like I said basic stuff. I'm using a switch since it makes my life 100000x easier than just using a bunch of if's and it's a nicer layout regardless.
The following is my code:
import java.util.Scanner;
import java.util.ArrayList;
public class Account
{
public static void main (String [] args)
{
Scanner sc = new Scanner (System.in);
ArrayList list = new ArrayList();
boolean quit = false;
do
{
System.out.println ("MENU\n 0: Enter name to list\n 1: Delete name from list\n 2: Print Current List\n 3: Quit");
int input = sc.nextInt();
switch(input)
{
case 0:
System.out.println ("Enter name to add to list");
list.add(sc.nextLine());
System.out.println("Name has been added");
System.out.println (list);
break;
case 1:
System.out.println("Enter name to remove");
list.remove(sc.next());
System.out.println (list);
break;
case 2:
System.out.println (list);
break;
case 3:
quit = true;
break;
default:
System.out.println ("Invalid choice");
}
}while(!quit);
System.out.println ("Exiting menu");
}
}
My issue is that once I enter 0 to go to the first case, it seems as though it just skips the user entry and outputs an empty string. If I were to do that exact same procedure outside of my switches it seems to work, so it makes me think that something might be up with my scanner. Possibly has something to do with the int scan I made right before to get into the case? But I could have sworn I've done something like this dozens of times...
I should also mention that sc.next() works fine, its just sc.nextLine() that seems to be giving me stress.

When you use a Scanner, if you want to use nextline() after next(), nextInt(), or nextDouble(), you have to put a nextLine() alone before the line where you get input, in order to consume the newline.
Or, to avoid having to account for this problem, instead of using nextInt(), and nextDouble(), just do:
Integer.parseInt(nextLine())//equivalent of nextInt() except no funny errors
Double.parseDouble(nextLine())//equivalent of nextDouble() without funny stuff

This is happening because the nextInt does not read the last newline character of the input, and that remaining newline is getting consumed in the next call to nextLine.
The same behavior can be noticed if we use nextLine after any of the nextXXX except for the nextLine itself
In order to solve this problem you can:
Either use a blank nextLine call after nextInt to consume the newline
int input = sc.nextInt();
sc.nextLine(); // Use this to consume the newline character
String input1 = sc.nextLine();
or you can use the workaround as mentioned by #kirbyquerby

Related

Unable to pass line to Scanner

Scanner kb=new Scanner(System.in);
System.out.println("\nDo you want to continue");
char answer=kb.next().charAt(0);
if(Character.toUpperCase(answer)=='Y') {
System.out.println("\nType any message to get Value");
String input=kb.nextLine();
class2 obj=new class2(input);
System.out.println("\n"+obj.getValue());
}
My program is not passing input to class2, it's just executing my method with empty input. I just tried every method, but none are working.
This will be solved by changing
char answer = kb.next().charAt(0);
to
char answer = kb.nextLine().charAt(0);
This is the solution because the next() method in Java does not advance the Scanner to the next line while nextLine() does.
You have two options:
1) make char answer=kb.nextLine().charAt(0);
2) make String input=kb.next();
Option 1: If you make it nextLine() it will consume the whole line and moves the cursor to next line. Thus there is no remaining string to be consumed.
Option 2: next() only consumes line till it finds a space and also it does not advances cursor to the next line. Thus for the first input if you type "yopo" the nextLine() will consume the remaining blank and you will not get anything.
In your case you should prefer the 1st option.

Scanner.next() and hasNext() creating infinite loop when reading from console [duplicate]

I ran into an issue. Below is my code, which asks user for input and prints out what the user inputs one word at a time.
The problem is that the program never ends, and from my limited understanding, it seem to get stuck inside the while loop. Could anyone help me a little?
import java.util.Scanner;
public class Test{
public static void main(String args[]){
System.out.print("Enter your sentence: ");
Scanner sc = new Scanner (System.in);
while (sc.hasNext() == true ) {
String s1 = sc.next();
System.out.println(s1);
}
System.out.println("The loop has been ended"); // This somehow never get printed.
}
}
You keep on getting new a new string and continue the loop if it's not empty. Simply insert a control in the loop for an exit string.
while(!s1.equals("exit") && sc.hasNext()) {
// operate
}
If you want to declare the string inside the loop and not to do the operations in the loop body if the string is "exit":
while(sc.hasNext()) {
String s1 = sc.next();
if(s1.equals("exit")) {
break;
}
//operate
}
The Scanner will continue to read until it finds an "end of file" condition.
As you're reading from stdin, that'll either be when you send an EOF character (usually ^d on Unix), or at the end of the file if you use < style redirection.
When you use scanner, as mentioned by Alnitak, you only get 'false' for hasNext() when you have a EOF character, basically... You cannot easily send and EOF character using the keyboard, therefore in situations like this, it's common to have a special character or word which you can send to stop execution, for example:
String s1 = sc.next();
if (s1.equals("exit")) {
break;
}
Break will get you out of the loop.
Your condition is right (though you should drop the == true). What is happening is that the scanner will keep going until it reaches the end of the input. Try Ctrl+D, or pipe the input from a file (java myclass < input.txt).
it doesn't work because you have not programmed a fail-safe into the code. java sees that the scanner can still collect input while there is input to be collected and if possible, while that is true, it keeps doing so. having a scanner test to see if a certain word, like EXIT for example, is fine, but you could also have it loop a certain number of times, like ten or so. but the most efficient approach is to ask the user of your program how many strings they wish to enter, and while the number of strings they enter is less than the number they put in, the program shall execute. an added option could be if they type EXIT, when they see they need less spaces than they put in and don't want to fill the next cells up with nothing but whitespace. and you could have the program ask if they want to enter more input, in case they realize they need to enter more data into the computer.
the program would be quite simplistic to make, as well because there are a plethera of ways you could do it. feel free to ask me for these ways, i'm running out of room though. XD
If you don't want to use an EOF character for this, you can use StringTokenizer :
import java.util.*;
public class Test{
public static void main(){
Scanner sc = new Scanner (System.in);
System.out.print("Enter your sentence: ");
String s=sc.nextLine();
StringTokenizer st=new StringTokenizer(s," ");//" " is the delimiter here.
while (st.hasMoreTokens() ) {
String s1 = st.nextToken();
System.out.println(s1);
}
System.out.println("The loop has been ended");
}
}
I had the same problem and I solved it by reading the full line from the console with one scanner object, and then parsing the resulting string using a second scanner object.
Scanner console = new Scanner(System.in);
System.out.println("Enter input here:");
String inputLine = console.nextLine();
Scanner input = new Scanner(inputLine);
List<String> arg = new ArrayList<>();
while (input.hasNext()) {
arg.add(input.next().toLowerCase());
}
You can simply use one of the system dependent end-of-file indicators ( d for Unix/Linux/Ubuntu, z for windows) to make the while statement false. This should get you out of the loop nicely. :)
Modify the while loop as below. Declare s1 as String s1; one time outside the loop. To end the loop, simply use ctrl+z.
while (sc.hasNext())
{
s1 = sc.next();
System.out.println(s1);
System.out.print("Enter your sentence: ");
}

Java: nextLine() skipping input and adding blank spaces to arrayList [duplicate]

This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 7 years ago.
I have this piece of code that is supposed to add String values to an arrayList through the Scanner's next() or nextLine() method. The problem with next() is that it ignores everything after the first white space so I get that I should use the nextLine() method instead. The problem with nextLine() is that that it doesn't record the input, instead it stores a couple of blank spaces into the arrayList. Here's the code:
System.out.println("\nWhat is your idea? ");
String i = in.nextLine();
in.nextLine();
meals.add(i);
System.out.println("\n" + i + " has been entered into the idea pool. \n");
System.in.read();
I added the extra "in.nextLine()" after the initial "String i = in.nextLine()" because that's the only fix I found when I researched this problem but it doesn't work for me, it just still just stores a couple of blank spaces. Also, the System.in.read(); at the end there is only there so that it doesn't just jump forward after taking the input.
Here is the code where the above sample fits into:
ArrayList<String> meals = new ArrayList<String>();
String select = "";
while(!select.equals("")){
System.out.println("What would you like to do?");
System.out.println("1. <Irrelevant>");
System.out.println("2. Enter an idea");
System.out.println("3. <Irrelevant>");
System.out.println("4. <Irrelevant>");
System.out.println("Q. <Irrelevant>");
select = in.next();
switch(select){
case "1":
//Some stuff here.
case "2":
//Here's where the above problem fits into.
case "3":
//More stuff here
//and so on...
}
}
The reason why you are facing such issue is because you are using firstly next() method to read the input, and the further inputs you are taking using nextLine().
next() accepts the input, and the input pointer stays on the same line as of the current input.
So, as soon as you enter your choice and hit Enter, the choice is saved into the select variable, but, the input pointer is still on the same line. You should use a nextLine() to move the pointer to a new line.
Then you should use any number of nextLine()'s to receive multiple lines.
Also, remove an extra nextLine() method call from the case 2 statement. Remove the System.in.read() too, as your problem would have been solved.
ArrayList<String> meals = new ArrayList<String>();
String select = "";
while(!select.equals("")){
System.out.println("What would you like to do?");
System.out.println("1. <Irrelevant>");
System.out.println("2. Enter an idea");
System.out.println("3. <Irrelevant>");
System.out.println("4. <Irrelevant>");
System.out.println("Q. <Irrelevant>");
select = in.next();
in.nextLine(); // add this extra line in your code
switch(select){
case "1":
//Some stuff here.
case "2":
System.out.println("\nWhat is your idea? ");
String i = in.nextLine();
meals.add(i);
System.out.println("\n" + i + " has been entered into the idea pool. \n");
case "3":
//More stuff here
//and so on...
}

Java Using Scanner Multiple Times [duplicate]

This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 26 days ago.
I am having this problem a lot. When I use a Scanner a lot of times, it doesn't get input from user.
Scanner scan = new Scanner(System.in);
System.out.println("1---");
int try1 = scan.nextInt();
System.out.println("2---");
int try2 = scan.nextInt();
System.out.println("3---");
String try3 = scan.nextLine();
System.out.println("4---");
String try4 = scan.nextLine();
When I run this code, result it :
1---
12
2---
321
3---
4---
aa
As you can see, it skipped at 3rd input. Why this is happening? I solve this problem by using new Scanners, sometimes I have 5-6 different Scanners and it looks so complicated.
Another problem is : there is an error "Resource leak: scan is never closed". I am really confused.
The problem is that by using scanner.nextInt() you only read an integer value, but not the whole line and you don't consume the newline character (\n) that is appended to the line when you press Enter.
Then, when you process reading with scanner.nextLine() you consume the newline character (\n) and from the previous row and don't read the line you want to read. In order to force it to read it, you have to add an additional input.nextLine() statement.
System.out.println("2---");
int try2 = scan.nextInt();
System.out.println("3---");
scan.nextLine(); //<-- fake statement, to move the cursor on the next line
String try3 = scan.nextLine();
Not related to the question, you have to close the Scanner, after finishing work, otherwise the compiler complains with a warning:
scan.close();
Use next API rather than nextLine as when you do nextInt you press enter and it generates number + \n and nextInt is only going to take an integer and won't take \n which in turn gets passed to next input i.e. try3 which is why it gets skipped.
Scanner scan = new Scanner(System.in);
System.out.println("1---");
int try1 = scan.nextInt();
System.out.println("2---");
int try2 = scan.nextInt();
System.out.println("3---");
String try3 = scan.next();
System.out.println("4---");
String try4 = scan.next();
Well, for the first question use
scan.next()
insted of using
scan.nextLine();
For the second question I'd recommend using try, assuming you need to close your scan as your compiler is warning: "Resource leak: scan is never closed"
Scanner scanner= null;
try {
scanner= new Scanner(System.in);
}
finally {
if(scanner!=null)
scanner.close();
}

How to get out of while loop in java with Scanner method "hasNext" as condition?

I ran into an issue. Below is my code, which asks user for input and prints out what the user inputs one word at a time.
The problem is that the program never ends, and from my limited understanding, it seem to get stuck inside the while loop. Could anyone help me a little?
import java.util.Scanner;
public class Test{
public static void main(String args[]){
System.out.print("Enter your sentence: ");
Scanner sc = new Scanner (System.in);
while (sc.hasNext() == true ) {
String s1 = sc.next();
System.out.println(s1);
}
System.out.println("The loop has been ended"); // This somehow never get printed.
}
}
You keep on getting new a new string and continue the loop if it's not empty. Simply insert a control in the loop for an exit string.
while(!s1.equals("exit") && sc.hasNext()) {
// operate
}
If you want to declare the string inside the loop and not to do the operations in the loop body if the string is "exit":
while(sc.hasNext()) {
String s1 = sc.next();
if(s1.equals("exit")) {
break;
}
//operate
}
The Scanner will continue to read until it finds an "end of file" condition.
As you're reading from stdin, that'll either be when you send an EOF character (usually ^d on Unix), or at the end of the file if you use < style redirection.
When you use scanner, as mentioned by Alnitak, you only get 'false' for hasNext() when you have a EOF character, basically... You cannot easily send and EOF character using the keyboard, therefore in situations like this, it's common to have a special character or word which you can send to stop execution, for example:
String s1 = sc.next();
if (s1.equals("exit")) {
break;
}
Break will get you out of the loop.
Your condition is right (though you should drop the == true). What is happening is that the scanner will keep going until it reaches the end of the input. Try Ctrl+D, or pipe the input from a file (java myclass < input.txt).
it doesn't work because you have not programmed a fail-safe into the code. java sees that the scanner can still collect input while there is input to be collected and if possible, while that is true, it keeps doing so. having a scanner test to see if a certain word, like EXIT for example, is fine, but you could also have it loop a certain number of times, like ten or so. but the most efficient approach is to ask the user of your program how many strings they wish to enter, and while the number of strings they enter is less than the number they put in, the program shall execute. an added option could be if they type EXIT, when they see they need less spaces than they put in and don't want to fill the next cells up with nothing but whitespace. and you could have the program ask if they want to enter more input, in case they realize they need to enter more data into the computer.
the program would be quite simplistic to make, as well because there are a plethera of ways you could do it. feel free to ask me for these ways, i'm running out of room though. XD
If you don't want to use an EOF character for this, you can use StringTokenizer :
import java.util.*;
public class Test{
public static void main(){
Scanner sc = new Scanner (System.in);
System.out.print("Enter your sentence: ");
String s=sc.nextLine();
StringTokenizer st=new StringTokenizer(s," ");//" " is the delimiter here.
while (st.hasMoreTokens() ) {
String s1 = st.nextToken();
System.out.println(s1);
}
System.out.println("The loop has been ended");
}
}
I had the same problem and I solved it by reading the full line from the console with one scanner object, and then parsing the resulting string using a second scanner object.
Scanner console = new Scanner(System.in);
System.out.println("Enter input here:");
String inputLine = console.nextLine();
Scanner input = new Scanner(inputLine);
List<String> arg = new ArrayList<>();
while (input.hasNext()) {
arg.add(input.next().toLowerCase());
}
You can simply use one of the system dependent end-of-file indicators ( d for Unix/Linux/Ubuntu, z for windows) to make the while statement false. This should get you out of the loop nicely. :)
Modify the while loop as below. Declare s1 as String s1; one time outside the loop. To end the loop, simply use ctrl+z.
while (sc.hasNext())
{
s1 = sc.next();
System.out.println(s1);
System.out.print("Enter your sentence: ");
}

Categories