am stuck with this question
6) Suppose you enter 34.3, the ENTER key, 57.8, the ENTER key, 789, the ENTER key. Analyze the following code.
Scanner scanner = new Scanner(System.in);
int value = scanner.nextDouble();
int doubleValue = scanner.nextInt();
String line = scanner.nextLine();
i know the answer, the line will be equal to '\n' when the last statement is executed but why?
can anyone please explain it for me please?
The Scanner reads as many tokens as necessary to get it's next output and then leaves all of the rest of the tokens there to be examined. nextInt() does not need the newline character so it leaves it in the token stream. When you call nextLine() it looks into the token stream, sees the newline character, and returns that.
Let's break this statement by statement.
Scanner scanner = new Scanner(System.in);
int value = scanner.nextDouble();
The system waits for you to type in the value.
34.3↲
The value is read as 34.3 but is truncated to 34 since it is stored as an integer. Now the next statement is executed.
int doubleValue = scanner.nextInt();
The system waits for you again to type in the value.
57.8↲
The value is read as 57 as you are using scanner.nextInt() and hence, the .8 is ignored. There is however a enter remaining in the buffer.
String line = scanner.nextLine();
The system now waits again for the input, and you type in this. The first new line is the remnant from the previous input.
↲
789↲
The scanner first sees the newline character, so it assumes that the line is terminated. So the value is read as \n
Hope this helps.
Related
For avoiding any unwanted character which has been entered in console like \n
we use nextInt() or nextLine() etc.
But in these cases actually the control is going a step ahead leaving the unwanted string or something like this.
But I want to delete or flush out the memory of buffer in which other unwanted data is taken by the system.
For example -->
Scanner scan=new Scanner(System.in);
scan.nextInt();
scan.nextline();//this statement will be skipped
because the system is taking \n as a line next to the integer given as input.
In this case without using scan.nextLine() I want to simply clear/flush out the buffer memory where the \n was stored.
Now please tell me how to delete the input buffer memory in java
Thank you. :)
You can use this to clear all existing data in the buffer:
while(sc.hasNext()) {
sc.next();
}
If you are only doing this to remove the newline (\n) characters from the input, you can use:
while(sc.hasNext("\n")) {
sc.next();
}
If the goal is to only read integers and skip any other characters, this would work:
while(sc.hasNext() && !sc.hasNextInt()) {
sc.next();
}
you can simply use one more scan.nextLine() before taking the string as input.
Scanner scan = new Scanner(System.in);
int x = scan.nextInt();
scan.nextLine(); // clears the input buffer
String s = scan.nextLine(); // this statement won't get skip
Reference : the solution to this hackerrank question uses the same idea which I provided
My professor tends to do the following to get a number from the user:
Scanner scanner = new Scanner(System.in);
Integer.parseInt(scanner.nextLine());
What are the benefits as opposed to simply doing scanner.nextInt() ?
java.util.Scanner.java has the following in it:
public int nextInt() {
return nextInt(defaultRadix);
}
public int nextInt(int radix) {
// Check cached result
if ((typeCache != null) && (typeCache instanceof Integer)
&& this.radix == radix) {
int val = ((Integer)typeCache).intValue();
useTypeCache();
return val;
}
setRadix(radix);
clearCaches();
// Search for next int
try {
String s = next(integerPattern());
if (matcher.group(SIMPLE_GROUP_INDEX) == null)
s = processIntegerToken(s);
return Integer.parseInt(s, radix);
} catch (NumberFormatException nfe) {
position = matcher.start(); // don't skip bad token
throw new InputMismatchException(nfe.getMessage());
}
}
As I see it, Scanner calls Integer.parseInt() itself as well, on top of additional hocus pocus. Are there significant performance gains in doing simply Integer.parseInt(scanner.nextLine()) ? Are there on the other hand any drawbacks?
How about when scanning through a file with significant amount of data, and not a user input?
There are 2 observations :
Using myScannerInstance.nextInt() leaves behind a new line character. So, if you call nextLine() after nextInt(), the nextLine() will read the new line character instead of the actual data. Consequently, you will have to add another nextLine() after the nextInt() to gobble up that dangling new-line character. nextLine() doesn't leave behind a new line character.
code :
int age=myScannerInstance.nextInt();
String name = myScannerInstance.nextLine();// here the actual name will not be read. The new line character will be read.
nextInt() will again go back to the underlying stream and read. IO calls take time (expensive). It will do lot of checks to get the next integer. nextLine() will do those checks only once. So, if you call nextLine() once and read 5 integers (as a single line String), split them and parse them as integers (using Integer.parseInt()), it will be faster and more efficient than reading each int individually.
Using nextLine() + parseInt() will give you enormous performance benefit when you are running a very large loop.
Usage :
Using nextInt() gives you an additional advantage wherein you will get an exception if the input text is not an integer. example 123 is accepted.. 123sdsa will throw an InputMismatchException. So, you can catch it and handle it appropriately.
Using nextLine() will read the entire line, so, it will read the entire String sada1231 and then fail with NumberFormatException if it cannot parse the String as a number. You will have to handle that exception.
Generally, one nextLine() / nextInt() call won't make much of a difference. If you have a loop or if you are reading lot of data, then using readLine() with parseInt() will be very efficient.
nextInt() reads a number, but doesn’t consume line separator. While nextLine() reads the String and consumes the new-line character. According to Java Docs:
… 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.
In other words when you enter a number then press Enter, input.nextInt() consumes only the number, not the "end of line", primitive data types like int, double etc does not consume "end of line", due which this "end of line" remain in buffer ane When input.next() executes, it consumes the "end of line" from buffer from the first input. So you professor is trying to get to the next line after he reads the user input. You have to look at the logic of his codes only then you can understand it.
I also used to face this problem often. So i use to code like this..
public static void main(String[] args) {
Scanner key= new Scanner(System.in);
String name;
int age;
age = key.nextInt();
key.nextLine();
name = key.nextLine(); //to carry the new line character left behind nextInt()
System.out.println("Age : "+age);
System.out.println("Name: "+name);
}
here as the key.nextInt() leaves a new line character we are using key.nextLine() to carry the new Line character and then move to the nextline where the actual data is present. As we discussed above using Integer.parseInt() will be more efficient than using nextInt(). But this is also one of the way to code to overcome the problem.
nextInt() leaves behind a new line character. So, if you call nextLine() after nextInt() , the nextLine() will read the new line character instead of the actual data. Consequently, you will have to add another nextLine() after the nextInt() to gobble up that dangling new-line character.
public class Solution {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int i = scan.nextInt();
double d = scan.nextDouble();
scan.nextLine();
String s = scan.nextLine();
scan.close();
System.out.println("String: " + s);
System.out.println("Double: " + d);
System.out.println("Int: " + i);
}
}
I have following code and am facing a problem if I use System.in.read() before Scanner.
Then the cursor moves at the end by skipping nextLine() function.
import java.util.Scanner;
public class InvoiceTest{
public static void main(String [] args) throws java.io.IOException {
System.out.println("Enter a Charater: ");
char c = (char) System.in.read();
Scanner input = new Scanner(System.in);
System.out.println("Enter id No...");
String id_no = input.nextLine();
System.out.println("Charater You entered "+ c +" Id No Entered "+ id_no);
}
}
You are not consuming the newline character upon entering your character(System.in.read()) thus the input.nextLine() will consume it and skip it.
solution:
consume the new line character first before reading the input of for the id.
System.out.println("Enter a Charater: ");
char c = (char) System.in.read();
Scanner input = new Scanner(System.in);
System.out.println("Enter id No...");
input.nextLine(); //will consume the new line character spit by System.in.read()
String id_no = input.nextLine();
System.out.println("Charater You entered "+c+" Id No Entered "+id_no);
}
EJP comments thus:
Don't mix System.in.read() with new Scanner(System.in). Use one or the other.
Good advice!
So why is it a bad idea to mix reading from the stream and using Scanner?
Well, because Scanner operations will typically read ahead on the input stream, keeping unconsumed characters in an internal buffer. So if you do a Scanner operation followed by a call to read() on the stream, there is a good chance that the read() will (in effect) skip over characters. The behaviour is likely to be confusing and unpredictable ... and dependent on where the input characters are actually coming from.
If I comment out the line garbage = scan.nextLine();, the while-loop runs infinitely. Otherwise, it does not. I understand why it will run infinitely if there were only the print command, but I don't completely understand how the inclusion of the garbage variable stops it from running infintely. Can someone explain please?
import java.util.Scanner;
public class TypeSafeReadInteger
{
public static void main(String [] args)
{
Scanner scan = new Scanner(System.in);
String garbage;
System.out.print("Enter age as an integer > ");
while (! scan.hasNextInt())
{
garbage = scan.nextLine();
System.out.print("\nPlease enter an integer > ");
}
int age = scan.nextInt();
System.out.println("Your age is " + age);
}
}
garbage is just a variable, what 'stops' the while loop is the nextLine() It is a method that waits for user input. The while doesn't continue until your user inputs something using a keyboard and saves the input into the garbage variable.
You need to know two things:
hasNextLine() does not advance the Scanner instance.
nextLine() does advance the Scanner instance.
By "advance the Scanner instance", I mean "consume" input. Think of input as a stream, and think of a scanner object as something that is consuming that stream.
Things in a normal stream can only be consumed once. You captured your's in a variable called garbage, but you could just as easily have called scan.nextLine() without storing the result. I strongly advise you to read the Javadoc on Scanner to see which methods advance the Scanner instance and which do not.
To fix your code:
while (!scan.hasNextInt())
{
scan.nextLine(); // the order of the lines inside the loop makes the difference!
System.out.print("\nPlease enter an integer > ");
// when you perform nextLine() here - you reach the beginning of the loop
// without a token in the scanner - so you end up looping forever
}
int age = scan.nextInt();
By the way - as you can see from the example above, garbage is redundant.
If the user inputs an integer, then everything works. If they don't, then you get the infinite loop without the garbage = scan.nextLine(); line due to the way the Scanner class works.
When you do something like scan.hasNextInt();, no characters are actually read from the input. So if a user input something like "cat" in response to your prompt, then the input would be paused just before the first letter of that word. Since you are looping until there is an integer in the input, nothing further is read and you will loop infinitely because "cat" is just sitting in the input buffer.
By adding in the scan.nextLine() you will cause the Scanner to discard everything up to when the user hit <enter> and additional input could be processed.
sry about my english :)
Im new to Java programming and i have a problem with Scanner. I need to read an Int, show some stuff and then read a string so i use sc.nextInt(); show my stuff showMenu(); and then try to read a string palabra=sc.nextLine();
Some one told me i need to use a sc.nextLine(); after sc.nextInt(); but i dont understand why do you have to do it :(
Here is my code:
public static void main(String[] args) {
// TODO code application logic here
Scanner sc = new Scanner(System.in);
int respuesta = 1;
showMenu();
respuesta = sc.nextInt();
sc.nextLine(); //Why is this line necessary for second scan to work?
switch (respuesta){
case 1:
System.out.println("=== Palindromo ===");
String palabra = sc.nextLine();
if (esPalindromo(palabra) == true)
System.out.println("Es Palindromo");
else
System.out.println("No es Palindromo");
break;
}
}
Ty so much for your time and Help :D
nextInt() only reads in until it's found the int and then stops.
You have to do nextLine() because the input stream still has a newline character and possibly other non-int data on the line. Calling nextLine() reads in whatever data is left, including the enter the user pressed between entering an int and entering a String.
When you input a value (whether String, int, double, etc...) and hit 'enter,' a new-line character (aka '\n') will be appended to the end of your input. So, if you're entering an int, sc.nextInt() will only read the integer entered and leave the '\n' behind in the buffer. So, the way to fix this is to add a sc.nextLine() that will read the leftover and throw it away. This is why you need to have that one line of code in your program.