What is the main difference between next() and nextLine()?
My main goal is to read the all text using a Scanner which may be "connected" to any source (file for example).
Which one should I choose and why?
I always prefer to read input using nextLine() and then parse the string.
Using next() will only return what comes before the delimiter (defaults to whitespace). nextLine() automatically moves the scanner down after returning the current line.
A useful tool for parsing data from nextLine() would be str.split("\\s+").
String data = scanner.nextLine();
String[] pieces = data.split("\\s+");
// Parse the pieces
For more information regarding the Scanner class or String class refer to the following links.
Scanner: http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html
String: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html
next() can read the input only till the space. It can't read two words separated by a space. Also, next() places the cursor in the same line after reading the input.
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.
For reading the entire line you can use nextLine().
From JavaDoc:
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
next(): Finds and returns the next complete token from this scanner.
nextLine(): Advances this scanner past the current line and returns the input that was skipped.
So in case of "small example<eol>text" next() should return "small" and nextLine() should return "small example"
The key point is to find where the method will stop and where the cursor will be after calling the methods.
All methods will read information which does not include whitespace between the cursor position and the next default delimiters(whitespace, tab, \n--created by pressing Enter). The cursor stops before the delimiters except for nextLine(), which reads information (including whitespace created by delimiters) between the cursor position and \n, and the cursor stops behind \n.
For example, consider the following illustration:
|23_24_25_26_27\n
| -> the current cursor position
_ -> whitespace
stream -> Bold (the information got by the calling method)
See what happens when you call these methods:
nextInt()
read 23|_24_25_26_27\n
nextDouble()
read 23_24|_25_26_27\n
next()
read 23_24_25|_26_27\n
nextLine()
read 23_24_25_26_27\n|
After this, the method should be called depending on your requirement.
What I have noticed apart from next() scans only upto space where as nextLine() scans the entire line is that next waits till it gets a complete token where as nextLine() does not wait for complete token, when ever '\n' is obtained(i.e when you press enter key) the scanner cursor moves to the next line and returns the previous line skipped. It does not check for the whether you have given complete input or not, even it will take an empty string where as next() does not take empty string
public class ScannerTest {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int cases = sc.nextInt();
String []str = new String[cases];
for(int i=0;i<cases;i++){
str[i]=sc.next();
}
}
}
Try this program by changing the next() and nextLine() in for loop, go on pressing '\n' that is enter key without any input, you can find that using nextLine() method it terminates after pressing given number of cases where as next() doesnot terminate untill you provide and input to it for the given number of cases.
next() and nextLine() methods are associated with Scanner and is used for getting String inputs. Their differences are...
next() can read the input only till the space. It can't read two words separated by space. Also, next() places the cursor in the same line after reading the input.
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.
import java.util.Scanner;
public class temp
{
public static void main(String arg[])
{
Scanner sc=new Scanner(System.in);
System.out.println("enter string for c");
String c=sc.next();
System.out.println("c is "+c);
System.out.println("enter string for d");
String d=sc.next();
System.out.println("d is "+d);
}
}
Output:
enter string for c
abc def
c is abc
enter string for d
d is def
If you use nextLine() instead of next() then
Output:
enter string for c
ABC DEF
c is ABC DEF
enter string for d
GHI
d is GHI
In short: if you are inputting a string array of length t, then Scanner#nextLine() expects t lines, each entry in the string array is differentiated from the other by enter key.And Scanner#next() will keep taking inputs till you press enter but stores string(word) inside the array, which is separated by whitespace.
Lets have a look at following snippet of code
Scanner in = new Scanner(System.in);
int t = in.nextInt();
String[] s = new String[t];
for (int i = 0; i < t; i++) {
s[i] = in.next();
}
when I run above snippet of code in my IDE (lets say for string length 2),it does not matter whether I enter my string as
Input as :- abcd abcd or
Input as :-
abcd
abcd
Output will be like
abcd
abcd
But if in same code we replace next() method by nextLine()
Scanner in = new Scanner(System.in);
int t = in.nextInt();
String[] s = new String[t];
for (int i = 0; i < t; i++) {
s[i] = in.nextLine();
}
Then if you enter input on prompt as -
abcd abcd
Output is :-
abcd abcd
and if you enter the input on prompt as
abcd (and if you press enter to enter next abcd in another line, the input prompt will just exit and you will get the output)
Output is:-
abcd
From javadocs
next() Returns the next token if it matches the pattern constructed from the specified string.
nextLine() Advances this scanner past the current line and returns the input that was skipped.
Which one you choose depends which suits your needs best. If it were me reading a whole file I would go for nextLine until I had all the file.
From the documentation for Scanner:
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
From the documentation for next():
A complete token is preceded and followed by input that matches the delimiter pattern.
Just for another example of Scanner.next() and nextLine() is that like below :
nextLine() does not let user type while next() makes Scanner wait and read the input.
Scanner sc = new Scanner(System.in);
do {
System.out.println("The values on dice are :");
for(int i = 0; i < n; i++) {
System.out.println(ran.nextInt(6) + 1);
}
System.out.println("Continue : yes or no");
} while(sc.next().equals("yes"));
// while(sc.nextLine().equals("yes"));
Both functions are used to move to the next Scanner token.
The difference lies in how the scanner token is generated
next() generates scanner tokens using delimiter as White Space
nextLine() generates scanner tokens using delimiter as '\n' (i.e Enter
key presses)
A scanner breaks its input into tokens using a delimiter pattern, which is by default known the Whitespaces.
Next() uses to read a single word and when it gets a white space,it stops reading and the cursor back to its original position.
NextLine() while this one reads a whole word even when it meets a whitespace.the cursor stops when it finished reading and cursor backs to the end of the line.
so u don't need to use a delimeter when you want to read a full word as a sentence.you just need to use NextLine().
public static void main(String[] args) {
// TODO code application logic here
String str;
Scanner input = new Scanner( System.in );
str=input.nextLine();
System.out.println(str);
}
I also got a problem concerning a delimiter.
the question was all about inputs of
enter your name.
enter your age.
enter your email.
enter your address.
The problem
I finished successfully with name, age, and email.
When I came up with the address of two words having a whitespace (Harnet street) I just got the first one "harnet".
The solution
I used the delimiter for my scanner and went out successful.
Example
public static void main (String args[]){
//Initialize the Scanner this way so that it delimits input using a new line character.
Scanner s = new Scanner(System.in).useDelimiter("\n");
System.out.println("Enter Your Name: ");
String name = s.next();
System.out.println("Enter Your Age: ");
int age = s.nextInt();
System.out.println("Enter Your E-mail: ");
String email = s.next();
System.out.println("Enter Your Address: ");
String address = s.next();
System.out.println("Name: "+name);
System.out.println("Age: "+age);
System.out.println("E-mail: "+email);
System.out.println("Address: "+address);
}
The basic difference is next() is used for gettting the input till the delimiter is encountered(By default it is whitespace,but you can also change it) and return the token which you have entered.The cursor then remains on the Same line.Whereas in nextLine() it scans the input till we hit enter button and return the whole thing and places the cursor in the next line.
**
Scanner sc=new Scanner(System.in);
String s[]=new String[2];
for(int i=0;i<2;i++){
s[i]=sc.next();
}
for(int j=0;j<2;j++)
{
System.out.println("The string at position "+j+ " is "+s[j]);
}
**
Try running this code by giving Input as "Hello World".The scanner reads the input till 'o' and then a delimiter occurs.so s[0] will be "Hello" and cursor will be pointing to the next position after delimiter(that is 'W' in our case),and when s[1] is read it scans the "World" and return it to s[1] as the next complete token(by definition of Scanner).If we use nextLine() instead,it will read the "Hello World" fully and also more till we hit the enter button and store it in s[0].
We may give another string also by using nextLine(). I recommend you to try using this example and more and ask for any clarification.
The difference can be very clear with the code below and its output.
public static void main(String[] args) {
List<String> arrayList = new ArrayList<>();
List<String> arrayList2 = new ArrayList<>();
Scanner input = new Scanner(System.in);
String product = input.next();
while(!product.equalsIgnoreCase("q")) {
arrayList.add(product);
product = input.next();
}
System.out.println("You wrote the following products \n");
for (String naam : arrayList) {
System.out.println(naam);
}
product = input.nextLine();
System.out.println("Enter a product");
while (!product.equalsIgnoreCase("q")) {
arrayList2.add(product);
System.out.println("Enter a product");
product = input.nextLine();
}
System.out.println();
System.out.println();
System.out.println();
System.out.println();
System.out.println("You wrote the following products \n");
for (String naam : arrayList2) {
System.out.println(naam);
}
}
Output:
Enter a product
aaa aaa
Enter a product
Enter a product
bb
Enter a product
ccc cccc ccccc
Enter a product
Enter a product
Enter a product
q
You wrote the following products
aaa
aaa
bb
ccc
cccc
ccccc
Enter a product
Enter a product
aaaa aaaa aaaa
Enter a product
bb
Enter a product
q
You wrote the following products
aaaa aaaa aaaa
bb
Quite clear that the default delimiter space is adding the products separated by space to the list when next is used, so each time space separated strings are entered on a line, they are different strings.
With nextLine, space has no significance and the whole line is one string.
Related
This code finds the first word "horror", but does not show me the whole line, only the word found.
File f = new File("MyFile.txt");
Scanner scan = new Scanner(f);
while (scan.hasNextLine()) {
String str = scan.next();
if (str.contains("horror")) {
System.out.println(str + " este horror");
}
}
Why is that?
The Scanner class has many methods for reading different types, and each has a corresponding hasNext...() method, for example nextInt() and hasNextInt(). You checked hasNextLine(), but used next() which returns the next word instead of nextLine() which returns the next line.
Change your code from:
String str = scan.next(); // read next word ❌
to:
String str = scan.nextLine(); // read next line ✅
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.
import java.util.Scanner;
public class test{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter maximum number : ");
int items = input.nextInt();
String arr[] = new String[items];
int x = 0;
while(x < items)
{
System.out.println("Enter item " + x + ":");
arr[x] = input.nextLine();
x++;
}
}
}
On my code, First is I asked maximum number in an array index and store to arr[].
Now, I find error when I press enter and it displayed "Enter item 0" and "Enter item 1".
It displayed index arr[1] . What should be displayed is "Enter item 0" only at
my first press of enter. Does anybody know about this?
Thanks
The problem is that the nextInt() Scanner method does not handle the end of line (EOL) token, and so it is left dangling when you call input.nextInt() only to be snarfed up when you call input.nextLine() which does handle the EOL token.
One solution is to call nextLine() explicitly to handle the dangling token and to allow the Scanner to be ready for your next full line of input:
int items = input.nextInt();
input.nextLine(); // add this
When you create a line of text and press <enter>, an extra 1-2 characters are appended to the end of your text. A common one is called line feed, or LF, which is represented by numerically as decimal 10, and by a char of \n, and another one is called carriage return, or CR, and is represented numerically as 13, and char-wise as \r. Unix and Apple OS systems usually append just the LF while Windows/DOS systems append LF and CR together.
If you call input.nextInt() on a line of text, the Scanner will grab the int text, but will not grab the end of line tokens or chars mentioned above, and these characters will be left dangling or unhandled. If you you call input.nextInt() and there is more numeric input on the next line, then the Scanner will skip over the EOL tokens and get the number text, but if you call input.nextLine() the Scanner will grab the EOL tokens and nothing else.
I am writing a program that asks for the person's full name and then takes that input and reverses it (i.e John Doe - Doe, John). I started by trying to just get the input, but it is only getting the first name.
Here is my code:
public static void processName(Scanner scanner) {
System.out.print("Please enter your full name: ");
String name = scanner.next();
System.out.print(name);
}
Change to String name = scanner.nextLine(); instead of String name = scanner.next();
See more on documentation here - next() and nextLine()
Try replacing your code
String name = scanner.nextLine();
instead
String name = scanner.next();
next() can read the input only till the space. It can't read two words separated by space. Also, next() places the cursor in the same line after reading the input.
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.
From Scanner documentation:
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace.
and
public String 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.
This means by default the delimiter pattern is "whitespace". This splits your text at the space. Use nextLine() to get the whole line.
public static void processName(Scanner scanner) {
System.out.print("Please enter your full name: ");
scanner.nextLine();
String name = scanner.nextLine();
System.out.print(name);
}
Try the above code Scanner should be able to read space and move to the next reference of the String
scanner.next(); takes only the next word. scanner.nextLine(); should work. Hope this helps
In case you do not want to use .nextLine() you can also configure .next() to use \n as the delimiter pattern using .useDelimiter() method like so:
public static void processName(Scanner scanner) {
System.out.print("Please enter your full name: ");
scanner.useDelimiter("\n");
String name = scanner.next();
System.out.print(name);
}
try using this
String name = scanner.nextLine();
In this below program user enters the number of city name to be inserted and then a String array is initialized with that size.Then I try to iterate through loop and initialize every index of array with the value(City Name) inserted from user.
But when I tried to print value from array it ask for one less value..What I mean is if i say number of city is 2 ,so my loop should be iterated twice and twice I should insert value but instead i get to insert value only once.
On debugging i realized that the 0th element is getting inialized by itself from somewhere.I am not able to find the exact problem .
import java.util.Scanner;
public class EmptyStringGenerator {
public static void main(String []ard) {
Scanner scanner = new Scanner(System.in);
System.out.println("How many cities?");
String[]favoriteCities = new String[scanner.nextInt()];
for(int i=0;i<favoriteCities.length;i++){
favoriteCities[i]=scanner.nextLine();
}
for(String str:favoriteCities){
System.out.print(str+" ");
}
}
}
My Input:
2
Delhi
Output:
Delhi
The issue is that you read the int with nextInt(), but don't consume the line end! The rest of the line is left unprocessed, and the next nextLine() call goes on from that point.
nextLine() doc
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.
To correct the issue:
String[]favoriteCities = new String[scanner.nextInt()]; //read int
//consume line end, and do nothing with it
scanner.nextLine();
//now read the cities.
for(int i=0;i<favoriteCities.length;i++){
favoriteCities[i]=scanner.nextLine();
}
Recommended reading:
Scanner Java API doc
Line 0 is the end line after "2". nextInt() does not read that. Add a dummy nextLine() after reading the number.
Use next() method instead of nextLine().Since nextLine() reads the new line skipped by the nextInt() method .
nextLine()
Advances this scanner past the current line and returns the input that was skipped
next()
Finds and returns the next complete token from this scanner
So the code will be now
public static void main(String []ard)
{
Scanner scanner = new Scanner(System.in);
System.out.println("How many cities?");
String[]favoriteCities = new String[scanner.nextInt()];
for(int i=0;i<favoriteCities.length;i++)
{
favoriteCities[i]=scanner.next();
}
for(String str:favoriteCities)
{
System.out.print(str+" ");
}
}
If I understand the OP question correctly, input is int and city name, and the output should be number of times (int) the city name, say e.g 2 Delhi output Delhi Delhi, but he is getting only Delhi.
SOLUTION
String[]favoriteCities = new String[scanner.nextInt()];
String cityToBeAdded = scanner.next();
for(int i=0;i<favoriteCities.length;i++){
favoriteCities[i]=cityToBeAdded;
}
for(String str:favoriteCities){
System.out.print(str+" ");
}