私は入力を読むためにScanner
メソッドnextInt()
とnextLine()
を使っています。
それはこのように見えます:
System.out.println("Enter numerical value");
int option;
option = input.nextInt(); // Read numerical value from input
System.out.println("Enter 1st string");
String string1 = input.nextLine(); // Read 1st string (this is skipped)
System.out.println("Enter 2nd string");
String string2 = input.nextLine(); // Read 2nd string (this appears right after reading numerical value)
問題は、数値を入力した後、最初のinput.nextLine()
がスキップされ、2番目のinput.nextLine()
が実行されるため、出力が次のようになることです。
Enter numerical value
3 // This is my input
Enter 1st string // The program is supposed to stop here and wait for my input, but is skipped
Enter 2nd string // ...and this line is executed and waits for my input
私は自分のアプリケーションをテストしましたが、問題はinput.nextInt()
の使用にあるようです。削除した場合は、string1 = input.nextLine()
とstring2 = input.nextLine()
の両方が必要に応じて実行されます。
これは、 Scanner.nextInt
メソッドが「Enter」を押して作成された入力内のnewline文字を読み取らないため、 Scanner.nextLine
の呼び出しが は、newlineを読み取った後に戻ります。
Scanner.next()
または任意のScanner.nextLine
メソッド(nextLine
自体を除く)の後にScanner.nextFoo
を使用すると、同様の動作が発生します。
回避策:
各Scanner.nextLine
またはScanner.nextInt
の後にScanner.nextFoo
呼び出しを配置して、newlineを含むその行の残りを消費する
int option = input.nextInt();
input.nextLine(); // Consume newline left-over
String str1 = input.nextLine();
または、Scanner.nextLine
を使用して入力を読み取り、必要な適切な形式に入力を変換することもできます。たとえば、 Integer.parseInt(String)
メソッドを使用して整数に変換できます。
int option = 0;
try {
option = Integer.parseInt(input.nextLine());
} catch (NumberFormatException e) {
e.printStackTrace();
}
String str1 = input.nextLine();
問題は input.nextInt() メソッドにあります - それはint値を読むだけです。そのため、input.nextLine()で読み続けると、 "\ n" Enterキーが表示されます。これをスキップするには input.nextLine() を追加する必要があります。これが今明らかになっていることを願っています。
それを試してみてください。
System.out.print("Insert a number: ");
int number = input.nextInt();
input.nextLine(); // This line you have to add (It consumes the \n character)
System.out.print("Text1: ");
String text1 = input.nextLine();
System.out.print("Text2: ");
String text2 = input.nextLine();
それはあなたが数を入力するとき、それから押すからです Enter、input.nextInt()
は数字だけを消費し、 "行末"は消費しません。 input.nextLine()
が実行されると、最初の入力からまだバッファ内にある「行末」を消費します。
代わりに、input.nextLine()
の直後にinput.nextInt()
を使用してください。
Java.util.Scanner
に関しては、この問題について多くの質問があるようです。もっと読みやすく慣用的な解決策はscanner.skip("[\r\n]+")
を呼び出した後に改行文字を削除するためにnextInt()
を呼び出すことだと思います。
編集:@PatrickParkerが後述するように、これはユーザーが数の後に空白を入力すると無限ループを引き起こします。 skipと一緒に使うより良いパターンについては彼らの答えを見てください: https://stackoverflow.com/a/42471816/143585
input.nextInt();
が改行を捕らえていないからです。下にinput.nextLine();
を追加することで他の人が提案したようにすることができます。
あるいは、C#スタイルにしてnextLineを次のように整数に解析することもできます。
int number = Integer.parseInt(input.nextLine());
これを実行しても同様に機能し、コード行を節約できます。
少数の行を表すテキストには、行間に印刷できない文字も含まれています(行区切り文字と呼びます)
"\r"
として表される文字列リテラル)"\n"
として表される文字列リテラル)コンソールからデータを読み込んでいるとき、ユーザーは自分の応答を入力することができ、完了したら何らかの方法その事実を確認する必要があります。そのためには、ユーザーはキーボードの「Enter」/「Return」キーを押す必要があります。
重要なのは、ユーザーデータを標準入力(Scanner
によって読み取られるSystem.in
で表される)に配置することを保証することに加えて、このキーはOS依存の行区切り文字も送信することです(Windowsなど) \r\n
)その後。
したがって、ユーザーにage
などの値を要求し、ユーザーが42を入力してEnterキーを押すと、標準入力には"42\r\n"
が含まれます。
Scanner#nextInt
(およびその他のScanner#nextType
メソッド)では、スキャナーでconsumeこれらの行区切り文字を使用できません。標準入力から削除するSystem.in
(スキャナがage
値を表すユーザーからの数字が空白に直面するよりも多くないことをどのように知るか)から読み取りますが、また、cacheこれらの行区切り文字を内部的にします。覚えておく必要があるのは、すべてのScannerメソッドが常にキャッシュされたテキストからスキャンすることです。
Scanner#nextLine()
は、すべての文字を単に収集して返します行区切り文字が見つかるまで(またはストリームの終わり)。ただし、コンソールから数値を読み取った後の行区切り文字はスキャナーのキャッシュですぐに見つかるため、空の文字列を返します。つまり、スキャナーはそれらの行区切り文字(またはストリームの終わり)の前に文字を見つけることができませんでした。
BTW nextLine
また、consumesこれらの行区切り文字。
したがって、nextLine
の結果として空の文字列を避けながら、番号を要求してから行全体を要求する場合、
nextInt
によって残された行区切り文字を消費しますnextLine
を呼び出し、skip("\\R")
を呼び出して、スキャナが行区切りを表す\R
に一致する部分をスキップできるようにします(\R
の詳細: https://stackoverflow.com/a/31060125 )nextInt
(またはnext
、またはnextTYPE
メソッドも使用しないでください。代わりに、nextLine
を使用してデータ全体を行ごとに読み取り、各行の数値を解析して(1行に1つの数値のみが含まれる場合)、Integer.parseInt
を介してint
のような適切な型に変換します。BTW:Scanner#nextType
メソッドはskipデリミタ(デフォルトではタブ、行セパレータなどのすべての空白)を含む次の区切り文字以外の値(トークン)が見つかるまで、スキャナーによってキャッシュされます。 "42\r\n\r\n321\r\n\r\n\r\nfoobar"
コードのような入力のおかげで
int num1 = sc.nextInt();
int num2 = sc.nextInt();
String name = sc.next();
num1=42
num2=321
name=foobar
を適切に割り当てることができます。
input.nextLine()
の代わりにinput.next()
を使用すると、問題が解決します。
修正されたコード
public static Scanner input = new Scanner(System.in);
public static void main(String[] args)
{
System.out.print("Insert a number: ");
int number = input.nextInt();
System.out.print("Text1: ");
String text1 = input.next();
System.out.print("Text2: ");
String text2 = input.next();
}
この問題を回避するには、バッファをクリアするのに役立つので、nextLine();
の直後にnextInt();
を使用してください。 ENTER
を押すと、nextInt();
は改行をキャプチャしないため、後でScanner
コードをスキップします。
Scanner scanner = new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer
ScannerクラスのnextLine()メソッドに混乱することなく入力を高速にスキャンしたい場合は、カスタム入力スキャナを使用してください。
class ScanReader {
/**
* @author Nikunj Khokhar
*/
private byte[] buf = new byte[4 * 1024];
private int index;
private BufferedInputStream in;
private int total;
public ScanReader(InputStream inputStream) {
in = new BufferedInputStream(inputStream);
}
private int scan() throws IOException {
if (index >= total) {
index = 0;
total = in.read(buf);
if (total <= 0) return -1;
}
return buf[index++];
}
public char scanChar(){
int c=scan();
while (isWhiteSpace(c))c=scan();
return (char)c;
}
public int scanInt() throws IOException {
int integer = 0;
int n = scan();
while (isWhiteSpace(n)) n = scan();
int neg = 1;
if (n == '-') {
neg = -1;
n = scan();
}
while (!isWhiteSpace(n)) {
if (n >= '0' && n <= '9') {
integer *= 10;
integer += n - '0';
n = scan();
}
}
return neg * integer;
}
public String scanString() throws IOException {
int c = scan();
while (isWhiteSpace(c)) c = scan();
StringBuilder res = new StringBuilder();
do {
res.appendCodePoint(c);
c = scan();
} while (!isWhiteSpace(c));
return res.toString();
}
private boolean isWhiteSpace(int n) {
if (n == ' ' || n == '\n' || n == '\r' || n == '\t' || n == -1) return true;
else return false;
}
public long scanLong() throws IOException {
long integer = 0;
int n = scan();
while (isWhiteSpace(n)) n = scan();
int neg = 1;
if (n == '-') {
neg = -1;
n = scan();
}
while (!isWhiteSpace(n)) {
if (n >= '0' && n <= '9') {
integer *= 10;
integer += n - '0';
n = scan();
}
}
return neg * integer;
}
public void scanLong(long[] A) throws IOException {
for (int i = 0; i < A.length; i++) A[i] = scanLong();
}
public void scanInt(int[] A) throws IOException {
for (int i = 0; i < A.length; i++) A[i] = scanInt();
}
public double scanDouble() throws IOException {
int c = scan();
while (isWhiteSpace(c)) c = scan();
int sgn = 1;
if (c == '-') {
sgn = -1;
c = scan();
}
double res = 0;
while (!isWhiteSpace(c) && c != '.') {
if (c == 'e' || c == 'E') {
return res * Math.pow(10, scanInt());
}
res *= 10;
res += c - '0';
c = scan();
}
if (c == '.') {
c = scan();
double m = 1;
while (!isWhiteSpace(c)) {
if (c == 'e' || c == 'E') {
return res * Math.pow(10, scanInt());
}
m /= 10;
res += (c - '0') * m;
c = scan();
}
}
return res * sgn;
}
}
ScanReader sc = new ScanReader(System.in);
3.必要なクラスをインポートします。
import Java.io.BufferedInputStream; import Java.io.IOException; import Java.io.InputStream;
4.メインメソッドからIOExceptionをスローして、例外を処理します。5. Provided Methodsを使用します。 6.楽しむ
import Java.io.BufferedInputStream;
import Java.io.IOException;
import Java.io.InputStream;
class Main{
public static void main(String... as) throws IOException{
ScanReader sc = new ScanReader(System.in);
int a=sc.scanInt();
System.out.println(a);
}
}
class ScanReader....
文字列と整数の両方を読みたい場合、解決策は2つのスキャナを使うことです。
Scanner stringScanner = new Scanner(System.in);
Scanner intScanner = new Scanner(System.in);
intScanner.nextInt();
String s = stringScanner.nextLine(); // unaffected by previous nextInt()
System.out.println(s);
intScanner.close();
stringScanner.close();
sc.nextLine()
は、入力を解析するよりも優れています。性能面では賢明でしょう。
私はパーティーにかなり遅れていると思います。
前述のように、int値を取得した後にinput.nextLine()
を呼び出すと問題が解決します。あなたのコードがうまくいかなかった理由はあなたの入力(あなたがintを入力した場所)からstring1
に格納するものが他になかったからです。トピック全体にもう少し光を当てます。
Scannerクラスの nextFoo() メソッドのうち、 nextLine() を奇数として考えます。簡単な例を見てみましょう。以下のような2行のコードがあるとしましょう。
int firstNumber = input.nextInt();
int secondNumber = input.nextInt();
以下の値を(単一行の入力として)入力した場合
54 234
firstNumber
とsecondNumber
変数の値はそれぞれ54と234になります。これがこのように機能するのは、nextInt( すなわち\ n ) IS NOT が自動的に生成されるからです。 )メソッドは値を取り込みます。それは単に "next int" をとって先へ進む。これは、nextLine()以外の他のnextFoo()メソッドと同じです。
nextLine()は値を取った直後に改行を生成します。これは@RohitJainが改行が「消費される」と言うことによって意味するものです。
最後に、next()メソッドは単に最も近いString withoutを受け取り、新しい行を生成します。これは、これを同じ単一行内で別々の文字列を取るための優先的な方法にします。
これが役に立つことを願っています..メリーコーディング!
1つではなく2つのスキャナオブジェクトを使う
Scanner input = new Scanner(System.in);
System.out.println("Enter numerical value");
int option;
Scanner input2 = new Scanner(System.in);
option = input2.nextInt();
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int i = scan.nextInt();
scan.nextLine();
double d = scan.nextDouble();
scan.nextLine();
String s = scan.nextLine();
System.out.println("String: " + s);
System.out.println("Double: " + d);
System.out.println("Int: " + i);
}