扫描仪在使用 next() 或 nextFoo() 后跳过 nextLine()?

发布于 2024-11-29 22:08:05 字数 1020 浏览 1 评论 0原文

我使用 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() 都会按照我想要的方式执行。

I am using the Scanner methods nextInt() and nextLine() for reading input.

It looks like this:

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)

The problem is that after entering the numerical value, the first input.nextLine() is skipped and the second input.nextLine() is executed, so that my output looks like this:

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

I tested my application and it looks like the problem lies in using input.nextInt(). If I delete it, then both string1 = input.nextLine() and string2 = input.nextLine() are executed as I want them to be.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(25

爱,才寂寞 2024-12-06 22:08:05

这是因为 Scanner.nextInt 方法不会读取通过按“Enter”创建的输入中的换行字符,因此调用 <代码> Scanner.nextLine 在读取该换行符后返回。

Scanner.next() 或任何 Scanner.nextFoo 方法(除了下一行本身)。

解决方法:

  • 在每个 Scanner.nextIntScanner.nextFoo 之后调用 Scanner.nextLine消耗该行的其余部分,包括换行

     int option = input.nextInt();
     输入.nextLine(); // 消耗剩余的换行符
     字符串 str1 = input.nextLine();
    
  • 或者,更好的是,通过 Scanner.nextLine 读取输入并将输入转换为您需要的正确格式。例如,您可以使用 Integer.parseInt(String) 方法:

     int 选项 = 0;
     尝试 {
         选项 = Integer.parseInt(input.nextLine());
     } catch (NumberFormatException e) {
         e.printStackTrace();
     }
     字符串 str1 = input.nextLine();
    

That's because the Scanner.nextInt method does not read the newline character in your input created by hitting "Enter" and so the call to Scanner.nextLine returns after reading that newline.

You will encounter the similar behaviour when you use Scanner.nextLine after Scanner.next() or any Scanner.nextFoo method (except nextLine itself).

Workaround:

  • Either put a Scanner.nextLine call after each Scanner.nextInt or Scanner.nextFoo to consume the rest of that line including newline:

     int option = input.nextInt();
     input.nextLine();  // Consume left over newline
     String str1 = input.nextLine();
    
  • Or, even better, read the input through Scanner.nextLine and convert your input to the proper format you need. For example, you may convert to an integer using the Integer.parseInt(String) method:

     int option = 0;
     try {
         option = Integer.parseInt(input.nextLine());
     } catch (NumberFormatException e) {
         e.printStackTrace();
     }
     String str1 = input.nextLine();
    
你与昨日 2024-12-06 22:08:05

问题出在 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();

The problem is with the input.nextInt() method; it only reads the int value. So when you continue reading with input.nextLine() you receive the "\n" Enter key. So to skip this you have to add the input.nextLine().

Try it like this, instead:

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();
陌上芳菲 2024-12-06 22:08:05

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

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

It's because when you enter a number then press Enter, input.nextInt() consumes only the number, not the "end of line". When input.nextLine() executes, it consumes the "end of line" still in the buffer from the first input.

Instead, use input.nextLine() immediately after input.nextInt()

惟欲睡 2024-12-06 22:08:05

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

编辑:正如@PatrickParker 下面指出的,如果用户在数字后输入任何空格,这将导致无限循环。请参阅他们的答案,了解与跳过一起使用的更好模式:https://stackoverflow.com/a/42471816/143585

There seem to be many questions about this issue with java.util.Scanner. I think a more readable/idiomatic solution would be to call scanner.skip("[\r\n]+") to drop any newline characters after calling nextInt().

EDIT: as @PatrickParker noted below, this will cause an infinite loop if user inputs any whitespace after the number. See their answer for a better pattern to use with skip: https://stackoverflow.com/a/42471816/143585

北城孤痞 2024-12-06 22:08:05

TL;博士
当 (a) 这是第一个读取指令,(b) 上一个读取指令也是 nextLine() 时,调用 nextLine() 是安全的。

如果您不确定上述任一情况是否正确,您可以在调用 scanner.nextLine() 之前使用 scanner.skip("\\R?") 因为像 < code>next() nextInt() 将留下潜在的行分隔符 - 由 return 键创建,这将影响 nextLine() 的结果>。 .skip("\\R?") 让我们使用这个不必要的行分隔符。

skip 使用正则表达式,其中

  • \R 表示行分隔符
  • ? 将使 \R 可选 - 这将阻止 跳过方法:
    • 等待匹配序列
      • 如果到达仍然开放的数据源的末尾,例如 System.in、来自套接字的输入流等。
    • 在以下情况下抛出java.util.NoSuchElementException
      • 终止/关闭数据源,
      • 或者当现有数据与我们想要跳过的数据不匹配时

您需要知道的事情:

  • 代表几行的文本还包含行之间的不可打印字符(我们称之为行分隔符),例如

  • 回车符(CR - 在字符串文字中表示为 "\r"

  • 换行(LF - 在字符串文字中表示为 "\n"

  • 当您从控制台读取数据时,它允许用户输入他的响应,当他完成时,他需要以某种方式证实了这一事实。为此,用户需要按键盘上的“enter”/“return”键。

重要的是,除了确保将用户数据放置到标准输入(由 System.in 表示,由 Scanner 读取)之外,此键还发送其后是依赖于操作系统的行分隔符(如 Windows \r\n)。

因此,当您向用户询问诸如 age 这样的值时,用户输入 42 并按 Enter 键,标准输入将包含 "42\r\n"

问题

Scanner#nextInt(以及其他 Scanner#nextType 方法)不允许 Scanner 消耗这些行分隔符。它将从 System.in 读取它们(扫描仪如何知道用户中没有比面对空格更多的代表年龄值的数字?),这将删除它们来自标准输入,但它还会在内部缓存这些行分隔符。我们需要记住的是,所有 Scanner 方法始终从缓存的文本开始扫描。

现在,Scanner#nextLine() 只是收集并返回所有字符,直到找到行分隔符(或流末尾)。但是,由于从控制台读取数字后立即在 Scanner 的缓存中找到行分隔符,因此它返回空字符串,这意味着 Scanner 无法在这些行分隔符(或流末尾)之前找到任何字符。
顺便说一句,nextLine使用这些行分隔符。

解决方案

因此,当您想要请求数字,然后请求整行,同时避免 nextLine 结果出现空字符串时,可以

  • 从扫描仪缓存中消耗 nextInt 留下的行分隔符
  • 通过调用 nextLine
  • 或 IMO 更具可读性的方式是调用 skip("\\R")skip("\r\n|\r|\n") 让扫描仪跳过与行分隔符匹配的部分(有关 \R 的更多信息:https://stackoverflow.com/a/31060125
  • 不要使用 nextInt (也不要使用 next,或任何nextTYPE 方法)。而是使用 nextLine 逐行读取整个数据,并通过 Integer 将每一行中的数字(假设一行仅包含一个数字)解析为正确的类型,例如 int .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< /code> num2=321 name=foobar

TL;DR
nextLine() is safe to call when (a) it is first reading instruction, (b) previous reading instruction was also nextLine().

If you are not sure that either of above is true you can use scanner.skip("\\R?") before calling scanner.nextLine() since calls like next() nextInt() will leave potential line separator - created by return key which will affect result of nextLine(). The .skip("\\R?") will let us consume this unnecessary line separator.

skip uses regex where

  • \R represents line separators
  • ? will make \R optional - which will prevent skip method from:
    • waiting for matching sequence
      • in case of reaching end of still opened source of data like System.in, input stream from socket, etc.
    • throwing java.util.NoSuchElementException in case of
      • terminated/closed source of data,
      • or when existing data doesn't match what we want to skip

Things you need to know:

  • text which represents few lines also contains non-printable characters between lines (we call them line separators) like

  • carriage return (CR - in String literals represented as "\r")

  • line feed (LF - in String literals represented as "\n")

  • when you are reading data from the console, it allows the user to type his response and when he is done he needs to somehow confirm that fact. To do so, the user is required to press "enter"/"return" key on the keyboard.

What is important is that this key beside ensuring placing user data to standard input (represented by System.in which is read by Scanner) also sends OS dependant line separators (like for Windows \r\n) after it.

So when you are asking the user for value like age, and user types 42 and presses enter, standard input will contain "42\r\n".

Problem

Scanner#nextInt (and other Scanner#nextType methods) doesn't allow Scanner to consume these line separators. It will read them from System.in (how else Scanner would know that there are no more digits from the user which represent age value than facing whitespace?) which will remove them from standard input, but it will also cache those line separators internally. What we need to remember, is that all of the Scanner methods are always scanning starting from the cached text.

Now Scanner#nextLine() simply collects and returns all characters until it finds line separators (or end of stream). But since line separators after reading the number from the console are found immediately in Scanner's cache, it returns empty String, meaning that Scanner was not able to find any character before those line separators (or end of stream).
BTW nextLine also consumes those line separators.

Solution

So when you want to ask for number and then for entire line while avoiding that empty string as result of nextLine, either

  • consume line separator left by nextInt from Scanners cache by
  • calling nextLine,
  • or IMO more readable way would be by calling skip("\\R") or skip("\r\n|\r|\n") to let Scanner skip part matched by line separator (more info about \R: https://stackoverflow.com/a/31060125)
  • don't use nextInt (nor next, or any nextTYPE methods) at all. Instead read entire data line-by-line using nextLine and parse numbers from each line (assuming one line contains only one number) to proper type like int via Integer.parseInt.

BTW: Scanner#nextType methods can skip delimiters (by default all whitespaces like tabs, line separators) including those cached by scanner, until they will find next non-delimiter value (token). Thanks to that for input like "42\r\n\r\n321\r\n\r\n\r\nfoobar" code

int num1 = sc.nextInt();
int num2 = sc.nextInt();
String name = sc.next();

will be able to properly assign num1=42 num2=321 name=foobar.

乖乖兔^ω^ 2024-12-06 22:08:05

这样做是因为 input.nextInt(); 不捕获换行符。您可以像其他人建议的那样,通过在下面添加 input.nextLine(); 来实现。
或者,您也可以采用 C# 风格,并将 nextLine 解析为整数,如下所示:

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

这样做也同样有效,并且可以节省一行代码。

It does that because input.nextInt(); doesn't capture the newline. you could do like the others proposed by adding an input.nextLine(); underneath.
Alternatively you can do it C# style and parse a nextLine to an integer like so:

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

Doing this works just as well, and it saves you a line of code.

不忘初心 2024-12-06 22:08:05

使用 input.next() 而不是 input.nextLine() ,应该可以解决问题。

修改后的代码:

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

Instead of input.nextLine() use input.next(), that should solve the problem.

Modified code:

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();
}
半边脸i 2024-12-06 22:08:05

如果您想同时读取字符串和整数,解决方案是使用两个 Scanner:

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();

If you want to read both strings and ints, a solution is to use two Scanners:

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();
姐不稀罕 2024-12-06 22:08:05

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

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

In order to avoid the issue, use nextLine(); immediately after nextInt(); as it helps in clearing out the buffer. When you press ENTER the nextInt(); does not capture the new line and hence, skips the Scanner code later.

Scanner scanner =  new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer
夏末的微笑 2024-12-06 22:08:05

如果您想快速扫描输入而不混淆 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) - 扫描完成 Array(Integer)
  • scanLong(long[] array) - 扫描完成Array(Long)

用法:

  1. 复制 java 代码下方的给定代码。
  2. 为给定类初始化对象

ScanReader sc = new ScanReader(System.in);

3. 导入必要的类:

import java.io.BufferedInputStream;
导入java.io.IOException;
导入 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....

If you want to scan input fast without getting confused into Scanner class nextLine() method , Use Custom Input Scanner for it .

Code :

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

}

Advantages :

  • Scans Input faster than BufferReader
  • Reduces Time Complexity
  • Flushes Buffer for every next input

Methods :

  • scanChar() - scan single character
  • scanInt() - scan Integer value
  • scanLong() - scan Long value
  • scanString() - scan String value
  • scanDouble() - scan Double value
  • scanInt(int[] array) - scans complete Array(Integer)
  • scanLong(long[] array) - scans complete Array(Long)

Usage :

  1. Copy the Given Code below your java code.
  2. Initialise Object for Given Class

ScanReader sc = new ScanReader(System.in);

3. Import necessary Classes :

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;

4. Throw IOException from your main method to handle Exception
5. Use Provided Methods.
6. Enjoy

Example :

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....
蘸点软妹酱 2024-12-06 22:08:05

与解析输入相比,sc.nextLine() 更好。
因为性能方面它会很好。

sc.nextLine() is better as compared to parsing the input.
Because performance wise it will be good.

清风不识月 2024-12-06 22:08:05

我想我参加聚会已经很晚了。

如前所述,在获取 int 值后调用 input.nextLine() 将解决您的问题。您的代码不起作用的原因是您的输入(您输入 int 的位置)中没有任何其他内容可以存储到 string1 中。我将对整个主题进行更多的阐述。

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

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

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

54234

我们的 firstNumbersecondNumber 变量的值分别变为 54 和 234。之所以这样工作,是因为当 nextInt() 方法采用时,会自动生成一个新换行符(即 \n不会在价值观中。它只是简单地接受“下一个整数”并继续前进。除了 nextLine() 之外,其余的 nextFoo() 方法也是如此。

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

最后,next() 方法只是采用最近的字符串而不生成新行;这使得它成为在同一行中获取单独字符串的首选方法。

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

I guess I'm pretty late to the party..

As previously stated, calling input.nextLine() after getting your int value will solve your problem. The reason why your code didn't work was because there was nothing else to store from your input (where you inputted the int) into string1. I'll just shed a little more light to the entire topic.

Consider nextLine() as the odd one out among the nextFoo() methods in the Scanner class. Let's take a quick example.. Let's say we have two lines of code like the ones below:

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

If we input the value below (as a single line of input)

54 234

The value of our firstNumber and secondNumber variable become 54 and 234 respectively. The reason why this works this way is because a new line feed (i.e \n) IS NOT automatically generated when the nextInt() method takes in the values. It simply takes the "next int" and moves on. This is the same for the rest of the nextFoo() methods except nextLine().

nextLine() generates a new line feed immediately after taking a value; this is what @RohitJain means by saying the new line feed is "consumed".

Lastly, the next() method simply takes the nearest String without generating a new line; this makes this the preferential method for taking separate Strings within the same single line.

I hope this helps.. Merry coding!

鹿童谣 2024-12-06 22:08:05
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);
    }
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);
    }
胡大本事 2024-12-06 22:08:05

在我的一个用例中,我遇到了读取前面有几个整数值的字符串值的场景。我必须使用“for / while循环”来读取值。在这种情况下,上述建议都不起作用。

使用 input.next() 而不是 input.nextLine() 解决了该问题。希望这对处理类似情况的人有所帮助。

In one of my usecase, I had the scenario of reading a string value preceded by a couple of integer values. I had to use a "for / while loop" to read the values. And none of the above suggestions worked in this case.

Using input.next() instead of input.nextLine() fixed the issue. Hope this might be helpful for those dealing with similar scenario.

╰沐子 2024-12-06 22:08:05

如果我期望非空输入

避免:
– 如果以下输入被未经检查的 scan.nextLine() 作为解决方法,则会丢失数据
– 由于 scan.nextLine()scan.next() 替换,仅部分读取行而导致数据丢失 (输入:“yippie ya yeah” )
– 使用 Scanner 方法解析输入时抛出的异常(先读取,后解析)

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

if I expect a non-empty input

avoids:
–  loss of data if the following input is eaten by an unchecked scan.nextLine() as workaround
–  loss of data due to only partially read lines because scan.nextLine() was replaced by scan.next() (enter: "yippie ya yeah")
–  Exceptions that are thrown when parsing input with Scanner methods (read first, parse afterwards)

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

used in above example:

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
奶茶白久 2024-12-06 22:08:05

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

Scanner input = new Scanner(System.in);
System.out.println("Enter numerical value");    
int option;
Scanner input2 = new Scanner(System.in);
option = input2.nextInt();

Use 2 scanner objects instead of one

Scanner input = new Scanner(System.in);
System.out.println("Enter numerical value");    
int option;
Scanner input2 = new Scanner(System.in);
option = input2.nextInt();
匿名的好友 2024-12-06 22:08:05

由于 nextXXX() 方法不读取 newline,除了 nextLine() 之外。我们可以使用 scanner.skip()< 读取任何非字符串值(本例中为int)后跳过换行符 /代码>如下:

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

As nextXXX() methods don't read newline, except nextLine(). We can skip the newline after reading any non-string value (int in this case) by using scanner.skip() as below:

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);
逆夏时光 2024-12-06 22:08:05

使用此代码将解决您的问题。

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)

Use this code it will fix your problem.

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)
杯别 2024-12-06 22:08:05

要解决此问题,只需创建一个 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);
}

}

To resolve this problem just make a scan.nextLine(), where scan is an instance of the Scanner object. For example, I am using a simple HackerRank Problem for the explanation.

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

}

落花随流水 2024-12-06 22:08:05

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)

The nextLine() will read enter directly as an empty line without waiting for the text.

Simple solution by adding an extra scanner to consume the empty line:

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)
作业与我同在 2024-12-06 22:08:05

对于java初学者来说这是一个非常基本的问题。当我开始java(自学)时,我也遇到了同样的问题。
实际上,当我们获取整数数据类型的输入时,它仅读取整数值并保留 newLine(\n) 字符,并且当我们尝试获取新输入时,此行(即整数动态输入留下的新行)会产生问题。
例如。就像我们接受整数输入然后尝试接受字符串输入一样。

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

value2 将自动读取换行符并且不会接受用户输入。

解决方案
只是我们需要在接受下一个用户输入之前添加一行代码,

sc.nextLine();

即或

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

注意:不要忘记关闭扫描仪以防止内存泄漏;

This is a very basic problem for beginner coders in java. The same problem I also have faced when I started java (Self Taught).
Actually, when we take an input of integer dataType, it reads only integer value and leaves the newLine(\n) character and this line(i.e. leaved new line by integer dynamic input )creates the problem when we try to take a new input.
eg. Like if we take the integer input and then after try to take an String input.

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

the value2 will auto read the newLine character and will not take the user input.

Solution:
just we need to add one line of code before taking the next user input i.e.

sc.nextLine();

or

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

Note: don't forget to close the Scanner to prevent memory leak;

耳钉梦 2024-12-06 22:08:05

问题在于 input.nextInt() 方法 - 它只读取 int 值。因此,当您继续使用 input.nextLine() 阅读时,您会收到“\n”回车键。因此,要跳过此步骤,您必须添加 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();

The problem is with the input.nextInt() method - it only reads the int value. So when you continue reading with input.nextLine() you receive the "\n" Enter key. So to skip this you have to add the input.nextLine(). Hope this should be clear now.

Try it like that:

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();
花开浅夏 2024-12-06 22:08:05
 Scanner scan = new Scanner(System.in);
 int i = scan.nextInt();
 scan.nextLine(); // to Ignore the rest of the line after  (integer input)nextInt()
 double d=scan.nextDouble();
 scan.nextLine();
 String s=scan.nextLine();
 scan.close();
 System.out.println("String: " + s);
 System.out.println("Double: " + d);
 System.out.println("Int: " + i);
 Scanner scan = new Scanner(System.in);
 int i = scan.nextInt();
 scan.nextLine(); // to Ignore the rest of the line after  (integer input)nextInt()
 double d=scan.nextDouble();
 scan.nextLine();
 String s=scan.nextLine();
 scan.close();
 System.out.println("String: " + s);
 System.out.println("Double: " + d);
 System.out.println("Int: " + i);
沫雨熙 2024-12-06 22:08:05

使用BufferedReader类输入字符串,这不会产生问题

Use BufferedReader class to input string, this will not create problems

裂开嘴轻声笑有多痛 2024-12-06 22:08:05

为什么不在每次读取时都使用新的扫描仪?就像下面这样。通过这种方法,您将不会面对自己的问题。

int i = new Scanner(System.in).nextInt();

Why not use a new Scanner for every reading? Like below. With this approach you will not confront your problem.

int i = new Scanner(System.in).nextInt();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文