IT-Swarm.Net

在使用next()或nextFoo()之后,Scanner正在跳过nextLine()?

我使用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()并执行第二个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()都按我希望的那样执行。.

575
blekione

那是因为 Scanner.nextInt 方法没有通过点击“Enter”来读取你输入的newline字符,因此在读取newline之后调用 Scanner.nextLine 返回。.

Scanner.next() 或任何Scanner.nextLine方法之后使用Scanner.nextFoo时会遇到类似的行为(nextLine本身除外)。.

解决方法:

  • 在每个Scanner.nextLineScanner.nextInt之后调用Scanner.nextFoo来消耗该行的其余部分,包括newline

    int option = input.nextInt();
    input.nextLine();  // Consume newline left-over
    String str1 = input.nextLine();
    
  • 或者,更好的是,通过Scanner.nextLine读取输入并将输入转换为您需要的正确格式。例如,您可以使用 Integer.parseInt(String) method转换为整数。.

    int option = 0;
    try {
        option = Integer.parseInt(input.nextLine());
    } catch (NumberFormatException e) {
        e.printStackTrace();
    }
    String str1 = input.nextLine();
    
681
Rohit Jain

快速,可靠且价格合理的云托管

注册并在30天内获得$50奖金!

问题出在 input.nextInt() method - 它只读取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();
184
Prine

这是因为当你输入一个数字然后按 Enterinput.nextInt()只消耗数字,而不是“行尾”。当input.nextLine()执行时,它会消耗第一个输入中仍在缓冲区中的“行尾”。.

相反,在input.nextLine()之后立即使用input.nextInt()

74
Bohemian

Java.util.Scanner似乎有很多关于这个问题的问题。我认为更可读/惯用的解决方案是在调用scanner.skip("[\r\n]+")后调用nextInt()来删除任何换行符。.

编辑:正如下面提到的@PatrickParker,如果用户在数字后输入任何空格,这将导致无限循环。查看他们的答案以获得更好的模式以使用skip: https://stackoverflow.com/a/42471816/143585

39
Denis Tulskiy

这样做是因为input.nextInt();没有捕获换行符。你可以通过在下面添加一个input.nextLine();来像其他人那样做。.
或者您可以使用C#样式并将nextLine解析为整数,如下所示:

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

这样做也很有效,它为您节省了一行代码。.

29
Electric Coffee

你需要知道的事情:

  • 表示几行的文本也包含行之间的不可打印字符(我们称之为行分隔符)

    • 回车(CR - 用字符串文字表示为"\r"
    • 换行(LF - 在字符串文字中表示为"\n"
  • 当你从控制台读取数据时,它允许用户键入他的响应,当他完成时,他需要不知何故确认这一事实。为此,用户需要按键盘上的“输入”/“返回”键。.

    重要的是,除了确保将用户数据放置到标准输入(由System.inScannername__读取表示)之外,此密钥还会在其后发送OS相关行分隔符(如Windows \r\n)。.

    因此,当您向用户询问agename__之类的值,并且用户类型42并按Enter键时,标准输入将包含"42\r\n"。.

问题

Scanner#nextInt(和其他Scanner#nextType方法)不允许扫描程序消耗这些行分隔符。它将从System.in读取它们(扫描器如何知道用户没有更多的数字表示agename__值而不是面向空格?)这将从标准输入中删除它们,但是 它也将缓存内部的那些行分隔符 。我们需要记住的是,所有Scanner方法始终都是从缓存文本开始扫描的。.

现在Scanner#nextLine()只收集并返回所有字符直到找到行分隔符(或流的结尾)。但是,由于在扫描程序的缓存中立即找到从控制台读取数字后的行分隔符,它会返回空字符串,这意味着扫描程序无法在这些行分隔符(或流结束)之前找到任何字符。.
BTW nextLinename__也消耗那些行分隔符。.

因此,当您想要求数字然后是整行时,同时避免nextLinename__导致的空字符串,要么

  • 通过从扫描程序缓存中消耗nextIntname__留下的行分隔符
    • 调用nextLinename__,
    • 或者通过调用skip("\\R")让扫描程序跳过与\R匹配的部分,代表行分隔符(有关\R的更多信息: https://stackoverflow.com/a/31060125
  • 不要使用nextIntname__(也不是nextname__,或任何nextTYPEname__方法)。而是使用nextLinename__逐行读取整个数据,并通过Integer.parseInt将每行(假设一行只包含一个数字)的数字解析为正确的类型,如intname__。.

_ btw _ 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=42num2=321name=foobar。.

22
Pshemo

而不是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();
}
9
Castaldi

为了避免这个问题,请在nextLine();之后立即使用nextInt();,因为它有助于清除缓冲区。按ENTER时,nextInt();不捕获新行,因此稍后会跳过Scanner代码。.

Scanner scanner =  new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer
8
Urvashi Gupta

如果要快速扫描输入而不混淆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() - 扫描单个字符
  • scanInt() - 扫描整数值
  • scanLong() - 扫描长值
  • scanString() - 扫描字符串值
  • scanDouble() - 扫描双值
  • scanInt(int [] array) - 扫描完成数组(整数)
  • scanLong(long [] array) - 扫描完成数组(长)

用法:

  1. 将给定代码复制到Java代码下面。.
  2. 给定类的初始化对象

ScanReader sc = new ScanReader(System.in); 3.导入必要的类:

import Java.io.BufferedInputStream; import Java.io.IOException; import Java.io.InputStream; 4.从main方法抛出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....
8
NIKUNJ KHOKHAR

如果要读取字符串和整数,则解决方案是使用两个扫描程序:

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();
7
André Valenti

与解析输入相比,sc.nextLine()更好。因为表现明智,所以会很好。.

6
shankar upadhyay

我想我参加派对的时间已经很晚了..

如前所述,在获取int值后调用input.nextLine()将解决您的问题。你的代码不起作用的原因是因为没有其他东西可以从你的输入(你输入int的地方)存储到string1中。我只是对整个主题稍微透露一点。.

考虑 nextLine() 作为Scanner类中 nextFoo() 方法中的奇数。让我们举一个简单的例子..假设我们有两行代码,如下所示:

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

如果我们输入下面的值(作为单行输入)

54 234

我们的firstNumbersecondNumber变量的值分别变为54和234。之所以这样做是因为当nextInt()方法时自动生成一个新的换行符( ie\n IS NOT 接受价值观。它只需要 “next int” 并继续前进。除了nextLine()之外,其他nextFoo()方法也是如此。.

nextLine()在获取值后立即生成新换行符;这就是@RohitJain所说的新线路被“消耗”的意思。.

最后,next()方法只需要最近的String 没有 生成一个新行;这使得这成为在同一行中获取单独字符串的优先方法。.

我希望这有帮助..快乐编码!

2
Taslim Oseni

使用2个扫描仪对象而不是一个

Scanner input = new Scanner(System.in);
System.out.println("Enter numerical value");    
int option;
Scanner input2 = new Scanner(System.in);
option = input2.nextInt();
1
Harsh Shah
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);
    }
1
Neeraj Gahlawat