Write code like this in Java
Main1.java
import java.util.*;
/**
* Created 2017/05/23.
*/
public class Main1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> ary = new ArrayList<String>();
int num = sc.nextInt();
for (int i = 0; i < num; i++) {
String word = sc.nextLine();
ary.add(word);
}
System.out.println(ary);
}
}
Often in program contests 1: First receive the number input Receive more inputs for the number of times entered 2: 1 Input value of 3: 2 in various ways Because I needed a program like that Input the number of times → Write the input String in the form of storing in ArrayList However, the result of this execution is strange
Input value
2
a
b (cannot actually be entered)
Execution result
[, a]
A mysterious blank? I was in a situation where I was in, so I decided to investigate the cause ...
nextLine
public String nextLine() Advances the scanner to the current line and returns skipped input. This method returns the rest of the current line, excluding the last line delimiter. The position is set at the beginning of the next line. This method continues searching for the line delimiter in the input, so if the line delimiter does not exist, it may buffer all input that searches for lines to skip. Return value: Skipped lines exception: NoSuchElementException-if row not found IllegalStateException-if this scanner is closed
~~ Yeah, I don't know what you're talking about ~~ As a result of various investigations for the time being -.NextLine () also reads blanks (blank lines) I understood that But this time, I run into the question of where the blanks (blank lines) are coming from.
To check by writing the source code while actually examining it (it is much faster to move your hands than to worry about your head) The order of the source code file names is out of order, but please think that this is the result of various trials. ~~ I can't read this with just the reference ... ~~
First, let's take a quick look at the behavior of Scanner and .nextLine ().
Main5
Main5.java
import java.util.Scanner;
/**
* Created 2017/05/25.
*The behavior of nextLine
*/
public class Main5 {
public static void main(String[] args) {
String word = "123 test";
Scanner sc = new Scanner(word);
String line = sc.nextLine();
System.out.println(word);
//Execution result:123 test
System.out.println(line);
//Execution result:123 test
}
}
Execution result
123 test
123 test
This is very easy to understand
Main6 Next, try multiple scans
Main6.java
import java.util.Scanner;
/**
* Created 2017/05/25.
*/
public class Main6 {
public static void main(String[] args){
String word = "123 test";
Scanner sc = new Scanner(word);
int num = sc.nextInt();
String line = sc.nextLine();
System.out.println(word);
//Execution result:123test
System.out.println(num);
//Execution result: 123
System.out.println(line);
//Execution result: test
}
}
Execution result
123 test
123
test
What I want to pay attention to here is the output result of line. If you do .nextLine (); after doing .nextInt (); in advance, the number part has already been read. You can see that only blank + test remains
So what if you do .nextLine () after reading everything? Let's try it!
Main7
Main7.java
import java.util.Scanner;
/**
* Created 2017/05/25.
*/
public class Main7 {
public static void main(String[] args){
String word = "123 test";
Scanner sc = new Scanner(word);
int num = sc.nextInt();
String word2 = sc.next();
//String line = sc.nextLine();
//I get an error properly
//Exception in thread "main" java.util.NoSuchElementException: No line found
System.out.println(word);
//Execution result:123test
System.out.println(num);
//Execution result: 123
System.out.println(word2);
//Execution result:test
//System.out.println(line);
//Execution result:Not executed in the first place due to the above error
}
}
Execution result 1
123 test
123
test
Although it is written in the comment, if you uncomment .nextLine (); and execute it, an error will occur.
Execution result 2(.nextLine();Uncomment and run)
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at Java.Nexts.Main7.main(Main7.java:15)
This does not reveal the truth ... It will return an error like "There is no line!" However, if you add a little, the error will disappear.
Main8
Main8.java
import java.util.Scanner;
/**
* Created 2017/05/25.
*/
public class Main8 {
public static void main(String[] args){
String word = "123 test\n";
Scanner sc = new Scanner(word);
int num = sc.nextInt();
String word2 = sc.next();
String line = sc.nextLine();
System.out.println(word);//
//Execution result:123test
//
//There is a space (line feed) above
System.out.println(num);
//Execution result: 123
System.out.println(word2);
//Execution result:test
System.out.println(line);
//Execution result: (Blank)
//It's blank, but it's actually reading a blank line, so it doesn't mean that Line doesn't exist → it doesn't throw an error!
//System here.out.println(line);It's very easy to understand if you run it with debugging!
}
}
Execution result
123 test
123
test
Yes this is the truth Add the line feed code "\ n" at the String word. Then, after scanning up to word2, unlike Main7, line breaks will remain. String line = sc.nextLine (); reads as a line break (blank line) As a result, the line will contain an empty string.
This can be seen visually using the debug features of the IDE. You can see that there is a "" in the line
Now you can finally see if the code in Main1 behaved strangely. 1: First, when entering a numerical value, after hitting 2 and pressing enter, "2 \ n" is entered in the sc contents. When scanning with 2: int num = sc.nextInt () ;, num = 2 is stored and the content of sc is only "\ n" 3: After starting the loop, String word = sc.nextLine (); reads the current remaining sc content "\ n" and Store in ary as an empty string 4: The contents of sc are empty, so read and store the new input "a" here. 5: At this point, the loop stops because the process is performed twice. 6: The contents of ary become [, a]
In conclusion -Scanner returns the value of the current location (the part where the contents remain) -.NextLine () also reads blank lines It was a problem that occurred in the combined technique of
The fundamental solution is to create two scanners That way, you won't have to read the debris when entering numbers.
Main4.java
import java.util.ArrayList;
import java.util.Scanner;
/**
* Created 2017/05/25.
*Feeling that the cause was finally understood
*/
public class Main4 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Scanner sc2 = new Scanner(System.in);
ArrayList<String> ary = new ArrayList<String>();
int num = sc.nextInt();
for (int i = 0; i < num; i++) {
String word = sc2.nextLine();
ary.add(word);
}
System.out.println(ary);
}
input
2
a
b
Execution result
[a, b]
It's perfect!
Also, if you know that the string you enter is not space separated You can get the same result just by using .next ()
Main2.java
import java.util.*;
/**
* Created 2017/05/23.
*/
public class Main2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> ary = new ArrayList<String>();
int num = sc.nextInt();
for (int i = 0; i < num; i++) {
String word = sc.next();
ary.add(word);
}
System.out.println(ary);
}
}
input
2
a
b
Execution result
[a, b]
However, please note that the code of Main2 may behave unintentionally when you type a space-separated sentence.
2
a b c
Execution result
[a, b]
2017/5/25 postscript I got a smarter solution in the comments
Main9.java
import java.util.ArrayList;
import java.util.Scanner;
/**
* Created 2017/05/25.
*Get Qiita to teach you smarter ways
*/
public class Main9 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> ary = new ArrayList<String>();
int num = Integer.parseInt(sc.nextLine()); //Integer.Once converted to a complete number using parseInt, it can be read by nextLine!
for (int i = 0; i < num; i++) {
String word = sc.nextLine();
ary.add(word);
}
System.out.println(ary);
}
}
input
2
a
b
Execution result
[a, b]
First, .nextLine ()
treats the read result as a String type.
for that reason
int num = sc.nextLine();
If you write as it is
ʻError: (13, 26) java: Incompatible type: Unable to convert java.lang.String to int: And type inconsistency, and cannot be stored in int num However
int num = Integer.parseInt(sc.nextLine()); By writing, the value read by
.nextLine () can be converted to a numerical value, so it can be stored in ʻint num
!
This way of writing does not require multiple scanners
In addition, it's like calling .nextLine ()
for each line entered, which makes the code very straightforward.
~~ Java is troublesome ~~
Joking aside
I want to enter → Scanner sc = new Scanner (System.in);
I want to read line by line → .nextLine ();
It is undeniable that there was a copy-like idea that you should use.
This time, I understood well that I had an essential understanding of Scanner.
There are still many things I don't understand about Java, so I would like to continue studying hard.
2018/01/19 When I read it again after a long time, I was worried about it, so I corrected one You don't have to make a new scanner, just scan the whitespace once and it will work fine.
ScanSample.java
import java.util.ArrayList;
import java.util.Scanner;
/**
* Created 2018/01/19.
*correction
*/
public class ScanSample {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<String> ary = new ArrayList<String>();
int num = sc.nextInt();
String blank = sc.nextLine();
for (int i = 0; i < num; i++) {
String word = sc.nextLine();
ary.add(word);
}
System.out.println(ary);
}
}
input
2
a
b
Execution result
[a, b]
Recommended Posts