869

私は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()思い通りに実行されます。

4

23 に答える 23

1062

これは、メソッドが「Enter」を押して作成された入力の改行Scanner.nextInt文字を読み取らないため、その改行を読み取った後にへの呼び出しが返されるためです。Scanner.nextLine

Scanner.nextLineafterScanner.next()または任意のメソッド(それ自体Scanner.nextFooを除く)を使用すると、同様の動作が発生します。nextLine

回避策:

  • Scanner.nextLineそれぞれの後に電話をかけるかScanner.nextInt改行Scanner.nextFooを含むその行の残りを消費します

    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();
    
于 2012-10-27T16:39:20.083 に答える
254

問題は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();
于 2011-08-14T12:24:48.410 に答える
90

これは、数字を入力してからを押すEnterinput.nextInt()、「行末」ではなく、数字のみが消費されるためです。実行するinput.nextLine()と、最初の入力からバッファに残っている「行末」を消費します。

代わりに、input.nextLine()直後に使用してくださいinput.nextInt()

于 2011-08-14T12:25:35.503 に答える
50

でこの問題について多くの質問があるようですjava.util.Scannerscanner.skip("[\r\n]+")より読みやすい/慣用的な解決策は、を呼び出した後に改行文字を削除するために呼び出すことだと思いますnextInt()

編集:以下で説明する@PatrickParkerのように、ユーザーが数字の後に空白を入力すると、無限ループが発生します。スキップで使用するためのより良いパターンについては、彼らの答えを参照してください:https ://stackoverflow.com/a/42471816/143585

于 2014-03-23T16:35:12.077 に答える
35

input.nextInt();改行をキャプチャしないため、これを行います。下に追加することで、他の提案と同じように行うことができますinput.nextLine();
または、C#スタイルで実行し、nextLineを次のように整数に解析することもできます。

int number = Integer.parseInt(input.nextLine()); 

これを行うことも同様に機能し、コード行を節約できます。

于 2013-02-23T22:01:23.317 に答える
35

TL; DR前の命令がまたはであったかどうかわからない場合は、前に
使用します。scanner.skip("\\R?")scanner.nextLine()scanner.next()scanner.next*TypeName*()

skipここで正規表現を使用します

  • \R行区切り文字を表します

  • ?\R行区切りシーケンスをオプションにします-これにより、メソッドskip

    (a)一致するシーケンスを待機しています-データのソースがまだ開いているSystem.inが行区切り文字が見つからなかった場合
    (b)java.util.NoSuchElementExceptionデータのソースが終了/終了した場合(ファイルや文字列など)にスローします

あなたが知る必要があること:

  • 数行を表すテキストには、行の間に印刷できない文字(行区切り文字と呼びます)が含まれています。

  • キャリッジリターン(CR-として表される文字列リテラル"\r"

  • 改行(LF-として表される文字列リテラル内"\n"

  • コンソールからデータを読み取っているとき、ユーザーは自分の応答を入力できます。完了したら、何らかの方法でその事実を確認する必要があります。これを行うには、ユーザーはキーボードの「Enter」/「Return」キーを押す必要があります。

重要なのは、ユーザーデータを標準入力(によってSystem.in読み取られる)に配置することを保証することに加えて、このキーは、その後にScannerOS依存の行区切り記号(Windowsの場合など)も送信する\r\nことです。

したがって、ユーザーにのような値を要求し、ユーザーがage42と入力してEnterキーを押すと、標準入力にはが含まれます"42\r\n"

問題

Scanner#nextInt(および他の方法)Scannerがこれらの行区切り記号を使用することを許可しません。それらを読み取り(空白に面するよりも値を表す数字がユーザーから他にないことをスキャナーが知る方法はありますか?)、標準入力からそれらを削除しますが、それらの行区切り文字を内部キャッシュします。覚えておく必要があるのは、すべてのScannerメソッドは常にキャッシュされたテキストからスキャンしているということです。Scanner#nextTypeSystem.inage

これで、行区切り文字(またはストリームの終わり)が見つかるまで、Scanner#nextLine()すべての文字を収集して返すだけです。ただし、コンソールから数値を読み取った後の行区切り文字はスキャナーのキャッシュですぐに見つかるため、空の文字列が返されます。これは、スキャナーがそれらの行区切り文字(またはストリームの終わり)の前の文字を見つけることができなかったことを意味します。 ところで、これらの行区切り文字も使用します。
nextLine

解決

したがって、の結果としてその空の文字列を避けながら、番号を要求してから行全体を要求する場合はnextLine

  • nextIntスキャナーキャッシュから残された行区切り記号を消費する
  • 呼び出しnextLine
  • またはIMOのより読みやすい方法は、を呼び出すskip("\\R")skip("\r\n|\r|\n")、スキャナーに行区切り文字と一致する部分をスキップさせることです(詳細\Rhttps ://stackoverflow.com/a/31060125 )
  • nextInt(またはnext、または任意のnextTYPEメソッド)をまったく使用しないでください。代わりに、を使用してデータ全体を1行ずつ読み取り、nextLine各行の数値を解析して(1行に1つの数値しか含まれていないと想定)、intviaのような適切なタイプにしInteger.parseIntます。

ところで:メソッドは、次の非区切り値(トークン)が見つかるまで、スキャナーによってキャッシュされたものを含む区切り文字(デフォルトではタブや行区切り文字などのすべての空白)をスキップできます。コードのような入力をありがとうScanner#nextType"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

于 2016-10-09T22:51:41.067 に答える
18

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();
}
于 2014-07-23T10:20:51.480 に答える
16

文字列とintの両方を読み取りたい場合、解決策は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();
于 2017-06-20T18:52:41.693 に答える
13

この問題を回避するには、バッファをクリアするのに役立つため、nextLine();直後に使用してください。nextInt();を押すと、新しい行がキャプチャさENTERnextInt();ないため、Scanner後でコードがスキップされます。

Scanner scanner =  new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer
于 2016-11-17T00:51:29.130 に答える
13

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;
    }

}

利点:

  • BufferReaderよりも速く入力をスキャンします
  • 時間の複雑さを軽減します
  • 次の入力ごとにバッファをフラッシュします

方法:

  • scanChar()-1文字をスキャンします
  • scanInt()-整数値をスキャンします
  • scanLong()-Long値をスキャンします
  • scanString()-文字列値をスキャンします
  • scanDouble()-Double値をスキャンします
  • scanInt(int [] array)-完全なArray(Integer)をスキャンします
  • scanLong(long [] array)-完全なArray(Long)をスキャンします

使用法 :

  1. 指定されたコードをJavaコードの下にコピーします。
  2. 指定されたクラスのオブジェクトを初期化します

ScanReader sc = new ScanReader(System.in); 3.必要なクラスをインポートします。

import java.io.BufferedInputStream; import java.io.IOException; import java.io.InputStream; 4.メインメソッドからIOExceptionをスローして、例外を処理します。5.提供されたメソッドを使用します。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....
于 2017-06-16T08:12:55.220 に答える
10

sc.nextLine()入力を解析するよりも優れています。パフォーマンス的には良いでしょう。

于 2017-09-14T10:16:32.170 に答える
6

私はパーティーにかなり遅れていると思います。

前に述べたように、int値を取得した後に呼び出すとinput.nextLine()、問題が解決します。コードが機能しなかった理由は、入力(intを入力した場所)からに格納するものが他になかったためですstring1。トピック全体にもう少し光を当てます。

nextLine ()は、ScannerクラスのnextFoo()メソッドの中で奇妙なものと考えてください。簡単な例を見てみましょう。次のような2行のコードがあるとします。

int firstNumber = input.nextInt();
int secondNumber = input.nextInt();

以下の値を(1行の入力として)入力した場合

54 234

私たちfirstNumbersecondNumber変数の値はそれぞれ54と234になります。これがこのように機能する理由は、nextInt()メソッドが値を受け取るときに、新しい改行(つまり、\ n) が自動的に生成されないためです。それは単に「次のint」を取り、次に進みます。これは、nextLine()を除く残りのnextFoo()メソッドでも同じです。

nextLine()は、値を取得した直後に新しい改行を生成します。これは、@ RohitJainが、新しい改行が「消費された」と言うことを意味します。

最後に、next()メソッドは、改行を生成せずに最も近い文字列を取得します。これにより、これは同じ1行内で別々の文字列を取得するための優先的な方法になります。

これがお役に立てば幸いです。メリーコーディング!

于 2018-01-07T10:33:01.437 に答える
5
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);
    }
于 2017-07-30T03:48:25.933 に答える
5

空でない入力を期待する場合

回避策: –回避策として
次の入力がチェックされていないものに食われた場合のデータの損失–次のように置き換えられた ために部分的に読み取られた行のみによるデータの損失(入力: "yippie ya yeah") –  メソッドを使用して入力を解析するときにスローされる(最初に読み、後で解析します)scan.nextLine()
scan.nextLine()scan.next()
ExceptionScanner

public static Function<Scanner,String> scanLine = (scan -> {
    String s = scan.nextLine();
    return( s.length() == 0 ? scan.nextLine() : s );
  });


上記の例で使用:

System.out.println("Enter numerical value");    
int option = input.nextInt(); // read numerical value from input

System.out.println("Enter 1st string"); 
String string1 = scanLine.apply( input ); // read 1st string
System.out.println("Enter 2nd string");
String string2 = scanLine.apply( input ); // read 2nd string
于 2019-10-01T17:20:06.550 に答える
4

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();
于 2019-01-16T19:24:18.860 に答える
4

メソッドは、を除いて、をnextXXX()読み取らないため。以下のように使用することで、任意の値(この場合)を読み取った後をスキップできます。newlinenextLine()newlinenon-stringintscanner.skip()

Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
sc.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
System.out.println(x);
double y = sc.nextDouble();
sc.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
System.out.println(y);
char z = sc.next().charAt(0);
sc.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
System.out.println(z);
String hello = sc.nextLine();
System.out.println(hello);
float tt = sc.nextFloat();
sc.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
System.out.println(tt);
于 2019-12-18T09:08:48.230 に答える
4

私のユースケースの1つでは、2つの整数値が前に付いた文字列値を読み取るシナリオがありました。値を読み取るには、「 for/whileループ」を使用する必要がありました。そして、上記の提案はどれもこの場合はうまくいきませんでした。

問題を修正するinput.next()代わりに使用する。input.nextLine()これが同様のシナリオを扱っている人たちに役立つことを願っています。

于 2020-01-24T11:32:11.933 に答える
1

このコードを使用すると、問題が修正されます。

System.out.println("Enter numerical value");    
int option;
option = input.nextInt(); // Read numerical value from input
input.nextLine();
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)
于 2020-03-08T15:19:12.537 に答える
1

この問題を解決するには、 scan.nextLine()を作成します。ここで、scanはScannerオブジェクトのインスタンスです。たとえば、説明には単純なHackerRank問題を使用しています。

package com.company;
import java.util.Scanner;

public class hackerrank {
public static void main(String[] args) {
    Scanner scan = new Scanner(System.in);
    int i = scan.nextInt();
    double d = scan.nextDouble();
    scan.nextLine(); // This line shall stop the skipping the nextLine() 
    String s = scan.nextLine();
    scan.close();



    // Write your code here.

    System.out.println("String: " + s);
    System.out.println("Double: " + d);
    System.out.println("Int: " + i);
}

}

于 2020-12-31T14:10:24.440 に答える
1

nextLine()、テキストを待たずに、空の行として直接入力を読み取ります。

空の行を消費するためにスキャナーを追加することによる簡単な解決策:

System.out.println("Enter numerical value");    
int option;
option = input.nextInt(); // Read numerical value from input
input.nextLine();
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)
于 2021-08-15T10:55:02.590 に答える
0

すべての読み取りに新しいスキャナーを使用してみませんか?以下のように。このアプローチでは、問題に直面することはありません。

int i = new Scanner(System.in).nextInt();
于 2015-03-13T11:06:54.057 に答える
0

問題は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();
于 2020-11-22T06:59:57.867 に答える
0

これは、Javaの初心者コーダーにとって非常に基本的な問題です。私がjava(Self Taught)を始めたときに私が直面したのと同じ問題。実際、整数dataTypeの入力を取得すると、整数値のみを読み取り、newLine(\ n)文字を残します。この行(つまり、整数動的入力によって新しい行を残した)は、新しい入力を取得しようとしたときに問題を引き起こします。例えば。整数入力を取得してから、文字列入力を取得しようとした場合のように。

value1=sc.nextInt();
value2=sc.nextLine();

value2は、改行文字を自動的に読み取り、ユーザー入力を受け取りません。

解決策:次のユーザー入力を取得する前に、1行のコードを追加する必要があります。

sc.nextLine();

また

value1=sc.nextInt();
sc.nextLine();
value2=sc.nextLine();

注:メモリリークを防ぐために、スキャナーを閉じることを忘れないでください。

于 2021-11-11T08:29:52.493 に答える