Scanner is skipping nextLine() after using next() or nextFoo()?
我使用
它看起来像这样:
1 2 3 4 5 6 7 | 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) |
问题是在输入数值后,跳过第一个
1 2 3 4 | 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 |
我测试了我的应用程序,看起来问题在于使用
这是因为
在
解决方法:
-
在每个
Scanner.nextInt 或Scanner.nextFoo 之后调用Scanner.nextLine 来消耗该行的其余部分,包括换行符1
2
3int option = input.nextInt();
input.nextLine(); // Consume newline left-over
String str1 = input.nextLine(); -
或者,更好的是,通过
Scanner.nextLine 读取输入并将输入转换为您需要的正确格式。例如,您可以使用Integer.parseInt(String) 方法转换为整数。1
2
3
4
5
6
7int 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()。希望现在应该清楚这一点。
试试这样:
1 2 3 4 5 6 7 8 |
这是因为当你输入一个数字然后按Enter时,
而是在
]+")删除任何换行符。
编辑:正如下面提到的@PatrickParker,如果用户在数字后输入任何空格,这将导致无限循环。有关与skip一起使用的更好模式,请参阅他们的答案:https://stackoverflow.com/a/42471816/143585
这样做是因为
或者,您可以使用C#样式并将nextLine解析为整数,如下所示:
1 |
这样做也很有效,它为您节省了一行代码。
你需要知道的事情:
-
表示几行的文本也包含行之间的不可打印字符(我们称之为行分隔符)
-
回车(CR - 用字符串文字表示为
" )
" -
换行(LF - 在字符串文字中表示为
" )
"
-
回车(CR - 用字符串文字表示为
-
当你从控制台读取数据时,它允许用户输入他的回复,当他完成时,他需要以某种方式确认这一事实。为此,用户需要按键盘上的"输入"/"返回"键。
重要的是,除了确保将用户数据放置到标准输入(由
Scanner 表示,由Scanner 读取)之外,此键还会在其后发送OS相关行分隔符(如Windows)。
因此,当您向用户询问
age 之类的值,并且用户类型42并按Enter键时,标准输入将包含"42 "。
问题
现在
BTW
解
因此,当您想要求数字然后是整行时,同时避免因
-
使用扫描程序缓存中的
nextInt 消耗行分隔符-
调用
nextLine , -
或者通过调用
skip("\ 让扫描程序跳过与
") 匹配的部分,代表行分隔符(有关
的更多信息:https://stackoverflow.com/a/31060125)
-
调用
-
不要使用
nextInt (也不是next 或任何nextTYPE 方法)。而是使用nextLine 逐行读取整个数据,并将每行中的数字(假设一行只包含一个数字)解析为正确的类型,如int viaInteger.parseInt 。
BTW:
321
foobar"代码那样的输入
1 2 3 |
将能够正确分配
而不是
修改后的代码
1 2 3 4 5 6 7 8 9 10 11 |
如果要快速扫描输入而不混淆Scanner类的nextLine()方法,请使用自定义输入扫描程序。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | 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 == '\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) - 扫描完成数组(长)
用法:
3.导入必要的类:
import java.io.IOException;
import java.io.InputStream;
4.从main方法抛出IOException以处理Exception
5.使用提供的方法。
6.享受
示例:
1 2 3 4 5 6 7 8 9 10 11 | 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.... |
为避免此问题,请在
1 2 3 | Scanner scanner = new Scanner(System.in); int option = scanner.nextInt(); scanner.nextLine(); //clearing the buffer |
如果要读取字符串和整数,则解决方案是使用两个扫描程序:
1 2 3 4 5 6 7 8 9 |
与解析输入相比,
因为表现明智,所以会很好。
我想我参加派对的时间已经很晚了..
如前所述,在获取int值后调用
将nextLine()视为Scanner类中nextFoo()方法中的奇数。让我们举一个简单的例子..假设我们有两行代码,如下所示:
1 2 | int firstNumber = input.nextInt(); int secondNumber = input.nextInt(); |
如果我们输入下面的值(作为单行输入)
54 234
我们的
nextLine()在获取值后立即生成新换行符;这就是@RohitJain所说的新线路被"消耗"的意思。
最后,next()方法只是获取最近的String而不生成新行;这使得这成为在同一行中获取单独字符串的优先方法。
我希望这有帮助..快乐编码!
使用2个扫描仪对象而不是一个
1 2 3 4 5 |
1 2 3 4 5 6 7 8 9 10 11 12 |
为什么不在每次阅读时使用新的扫描仪?如下。使用这种方法,您将无法面对您的问题。
1 |