提问人:blekione 提问时间:10/28/2012 最后编辑:Liiblekione 更新时间:2/26/2023 访问量:844648
扫描仪在使用 next() 或 nextFoo() 后跳过了 nextLine()?
Scanner is skipping nextLine() after using next() or nextFoo()?
问:
我正在使用这些方法并读取输入。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()
答:
问题出在方法上;它只读取 int 值。因此,当您继续阅读时,您会收到“\n”Enter 键。因此,要跳过此操作,您必须添加 .input.nextInt()
input.nextLine()
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();
评论
Scanner.next()
Scanner.nextInt()
Scanner.next()
这是因为当您输入一个数字时,按 ,只消耗该数字,而不是“行尾”。执行时,它会消耗第一个输入仍在缓冲区中的“行尾”。Enterinput.nextInt()
input.nextLine()
取而代之的是,请在input.nextLine()
input.nextInt()
评论
Scanner.next()
Scanner.nextInt()
Scanner.next()
这是因为 Scanner.nextInt 方法不会读取通过按“Enter”创建的输入中的换行符,因此在读取该换行符后,对 Scanner.nextLine
的调用将返回。
当您在 Scanner.next
() 或任何方法(除了它本身)之后使用时,您也会遇到类似的行为。Scanner.nextLine
Scanner.nextFoo
nextLine
解决方法:
要么在每个之后调用一个调用,要么使用该行的其余部分,包括换行符
Scanner.nextLine
Scanner.nextInt
Scanner.nextFoo
int option = input.nextInt(); input.nextLine(); // Consume newline left-over String str1 = input.nextLine();
或者,更好的是,通读输入并将输入转换为您需要的正确格式。例如,您可以使用
Integer.parseInt(String)
方法转换为整数。Scanner.nextLine
int option = 0; try { option = Integer.parseInt(input.nextLine()); } catch (NumberFormatException e) { e.printStackTrace(); } String str1 = input.nextLine();
评论
try-catch
Integer.parseInt
NumberFormatException
Integer.parseInt("abc")
Scanner#hasNextFoo
而不是 try-catch,但这也有效。
它这样做是因为不捕获换行符。你可以像其他人一样,在下面添加一个。
或者,您可以采用 C# 样式并将 nextLine 解析为整数,如下所示:input.nextInt();
input.nextLine();
int number = Integer.parseInt(input.nextLine());
这样做也同样有效,它可以为您节省一行代码。
评论
Scanner.next()
Scanner.nextInt()
Scanner.next()
关于这个问题似乎有很多问题。我认为一个更具可读性/惯用的解决方案是在调用后调用以删除任何换行符。java.util.Scanner
scanner.skip("[\r\n]+")
nextInt()
编辑:如下@PatrickParker所述,如果用户在数字后输入任何空格,这将导致无限循环。请参阅他们的答案,以获得与 skip: https://stackoverflow.com/a/42471816/143585 一起使用的更好模式
评论
而不是使用,这应该可以解决问题。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();
}
评论
为什么不每次读数都使用新的扫描仪呢?如下图所示。使用这种方法,您将不会遇到您的问题。
int i = new Scanner(System.in).nextInt();
评论
Scanner
nextInt()
Scanner
TL;当 (a) 它是第一次阅读指令,(b) 之前的阅读指令也是 时,DR
是安全的。nextLine()
nextLine()
如果您不确定上述任何一项是否成立,则可以在调用之前使用,因为 like 调用会留下潜在的行分隔符 - 由 return 键创建,这将影响 的结果。将让我们使用这个不必要的行分隔符。scanner.skip("\\R?")
scanner.nextLine()
next()
nextInt()
nextLine()
.skip("\\R?")
skip
使用正则表达式,其中
\R
表示行分隔符?
将设为可选 - 这将阻止方法:\R
skip
- 等待匹配序列
- 如果到达仍然打开的数据源的末尾,例如,来自套接字的输入流等。
System.in
- 如果到达仍然打开的数据源的末尾,例如,来自套接字的输入流等。
- 在以下情况下投掷
java.util.NoSuchElementException
- 终止/关闭数据源,
- 或者当现有数据与我们想要跳过的数据不匹配时
- 等待匹配序列
你需要知道的事情:
表示几行的文本在行之间也包含不可打印的字符(我们称之为行分隔符),例如
回车符 (CR - 在字符串文本中表示为
"\r"
)换行符 (LF - 在字符串文字中表示为
"\n"
)当您从控制台读取数据时,它允许用户键入他的响应,当他完成时,他需要以某种方式确认这一事实。为此,用户需要按键盘上的“Enter”/“return”键。
重要的是,此键除了确保将用户数据置于标准输入(由其读取表示)之外,还会在其之后发送与操作系统相关的行分隔符(如Windows)。System.in
Scanner
\r\n
因此,当您要求用户输入诸如 的值时,如果用户键入 42 并按回车键,则标准输入将包含 。age
"42\r\n"
问题
Scanner#nextInt
(和其他方法)不允许 Scanner 使用这些行分隔符。它将从中读取它们(否则扫描仪怎么会知道用户没有更多的数字代表值而不是面对空格?),这将将它们从标准输入中删除,但它也会在内部缓存这些行分隔符。我们需要记住的是,所有 Scanner 方法始终从缓存的文本开始扫描。Scanner#nextType
System.in
age
现在只需收集并返回所有字符,直到找到行分隔符(或流的结尾)。但是,由于从控制台读取数字后的行分隔符会立即在 Scanner 的缓存中找到,因此它会返回空字符串,这意味着 Scanner 无法在这些行分隔符(或流结束)之前找到任何字符。
顺便说一句,也使用这些行分隔符。Scanner#nextLine()
nextLine
溶液
因此,当您想询问数字,然后询问整行,同时避免由于 而导致空字符串时,任一nextLine
- 使用扫描程序缓存中留下的行分隔符
nextInt
- 叫
nextLine
- 或 IMO 更具可读性的方式是通过调用或让扫描仪跳过由行分隔符匹配的部分(更多信息:https://stackoverflow.com/a/31060125
skip("\\R")
skip("\r\n|\r|\n")
\R
) - 根本不使用(也不是,或任何方法)。取而代之的是,使用每行逐行读取整个数据,并将每行中的数字(假设一行仅包含一个数字)解析为正确的类型,例如 via .
nextInt
next
nextTYPE
nextLine
int
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
为了避免这个问题,请立即使用,因为它有助于清除缓冲区。当您按 不会捕获新行,因此稍后会跳过代码。nextLine();
nextInt();
ENTER
nextInt();
Scanner
Scanner scanner = new Scanner(System.in);
int option = scanner.nextInt();
scanner.nextLine(); //clearing the buffer
如果你想快速扫描输入而不混淆到Scanner类nextLine()方法,请使用Custom Input Scanner。
法典:
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)
用法:
- 将给定代码复制到 java 代码下方。
- 初始化给定类的对象
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....
如果要同时读取字符串和整数,解决方案是使用两个扫描仪:
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();
评论
intScanner.close();
System.in
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);
}
评论
sc.nextLine()
与解析输入相比更好。
因为性能方面会很好。
我想我来晚了..
如前所述,在获取 int 值后调用将解决您的问题。您的代码不起作用的原因是,您的输入(您输入了 int 的位置)中没有其他东西可以存储。我将对整个主题进行更多说明。input.nextLine()
string1
将 nextLine() 视为 Scanner 类中 nextFoo() 方法中的奇数。让我们举一个简单的例子。假设我们有两行代码,如下所示:
int firstNumber = input.nextInt();
int secondNumber = input.nextInt();
如果我们输入下面的值(作为单行输入)
54 234
our 和 variable 的值分别变为 54 和 234。这样做的原因是,当 nextInt() 方法接收值时,不会自动生成新的换行符(即 \n)。它只是接受“下一个 int”并继续前进。除了 nextLine() 之外,其余的 nextFoo() 方法也是如此。firstNumber
secondNumber
nextLine() 在取值后立即生成新的换行符;这就是@RohitJain所说的新换行符已“消耗”的意思。
最后,next() 方法只取最近的 String,而不生成新行;这使得它成为在同一行中获取单独字符串的首选方法。
我希望这会有所帮助..祝您编码愉快!
评论
使用 2 个扫描仪对象而不是一个
Scanner input = new Scanner(System.in);
System.out.println("Enter numerical value");
int option;
Scanner input2 = new Scanner(System.in);
option = input2.nextInt();
如果我期望一个非空输入
避免: – 如果以下输入被未选中的解决方法吃掉,则数据丢失 – 由于仅部分读取行而丢失数据,因为被替换为 (enter:
“Yippie ya yes”) – 使用方法
解析输入时抛出的 s(先读取,后解析)scan.nextLine()
scan.nextLine()
scan.next()
Exception
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
评论
Scanner
close
Scanner
AutoCloseable
由于方法不读取 ,除了 .我们可以在读取任何值(在本例中)后跳过,如下所示:nextXXX()
newline
nextLine()
newline
non-string
int
scanner.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);
在我的一个用例中,我有一个场景是读取一个字符串值,前面有几个整数值。我不得不使用“for / while 循环”来读取值。在这种情况下,上述建议均无效。
使用而不是解决问题。希望这可能对那些处理类似情况的人有所帮助。input.next()
input.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)
评论
问题出在 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();
要解决此问题,只需创建一个 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);
}
}
将 enter 直接读取为空行,无需等待文本。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)
对于java初学者来说,这是一个非常基本的问题。当我开始java(自学成才)时,我也遇到了同样的问题。 实际上,当我们接受整数 dataType 的输入时,它只读取整数值并留下 newLine(\n) 字符,而这一行(即通过整数动态输入留下新行)在我们尝试接受新输入时会产生问题。 例如。就像我们接受整数输入,然后尝试接受 String 输入一样。
value1=sc.nextInt();
value2=sc.nextLine();
value2 将自动读取换行符,并且不会接受用户输入。
解决方案: 我们只需要在进行下一个用户输入之前添加一行代码,即
sc.nextLine();
或
value1=sc.nextInt();
sc.nextLine();
value2=sc.nextLine();
注意:不要忘记关闭扫描仪以防止内存泄漏;
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);
使用 BufferedReader 类输入字符串,这不会产生问题
上一个:如何让我的扫描仪识别我拥有的单词
评论