[使用Scanner
hasNextInt()
等hasNextDouble()
类方法时,我无法理解内存缓冲区的工作原理。请考虑以下代码,
Scanner in = new Scanner(System.in);
int number;
do {
System.out.print("Enter a positive integer: ");
while (!in.hasNextInt()) {
System.out.println("It's not an integer!");
in.next();
}
number = in.nextInt();
} while (number <= 0);
System.out.println("Your number is " + number);
一些随机值的输出:
Enter a positive integer: five
It's not an integer!
-1
Enter a positive integer: 45
Your number is 45
这里实际发生了什么?在第1行,当我输入five
时,嵌套的while
循环运行。 in.next()
的工作是什么?输入five
后,它说这不是整数!但是为什么不再次询问:输入一个正整数:吗?基本上,我希望相应的输出是这样的:
Enter a positive integer: five
It's not an integer!
Enter a positive integer: -1
It's not a positive integer!
Enter a positive integer: 45
Your number is 45.
我希望获得简短直观的解释,以了解如何在输入验证中处理white spaces
,line breaks
?什么是内存缓冲区?以及Scanner
类的不同方法(例如next()
,nextLine()
,nextInt()
,nextDouble()
等)如何操作?另外,如何避免重复不是整数!
Enter a positive number: five
It's not an integer!
one two three
It's not an integer!
It's not an integer!
It's not an integer!
10
Your number is 10
最后,为什么有很多人推荐try
catch
?
0,-1,-66,2352,+ 66都是整数值,因此您可能不太满意决定以其他方式指定它们。您的验证回复实际上应该是:
System.out.println("It's not a positive integer value!");
我个人从不使用那些,nextDouble()等方法,除非我想进行盲目验证。我只坚持一个循环,并使用nextLine()方法和String#matches()方法(带有一个小的Regular Expression)。我也不太在意使用try / catch来解决不需要的情况。nextInt()
Scanner in = new Scanner(System.in);
int number = 0;
while (number < 1) {
System.out.print("Enter a positive integer (q to quit): ");
String str = in.nextLine();
if (!str.equals("") && String.valueOf(str.charAt(0)).equalsIgnoreCase("q")) {
System.exit(0);
}
// If a string representation of a positive Integer value
// is supplied (even if it's prefixed with the '+' character)
// then convert it to Integer.
if (str.matches("\\+?\\d+") && !str.equals("0")) {
number = Integer.parseInt(str);
}
// Otherwise...
else {
System.err.println(str + " is not considered a 'positive' integer value!");
}
}
System.out.println("Your number is " + number);
在这个特定的用例中,我实际上发现它更具通用性,但是也许就是我。不管输入什么,您总是会得到一种形式或另一种形式的响应,并且您也有退出选项。要退出单词,以防nextInt()抛出NumberFormatException,因为提供了空格或数字以外的任何字符。然后,这将使您有机会显示一条消息,以控制台提供了无效的输入。由于quit
或字母q
(在任何字母情况下)。人们喜欢利用
try / catch
Scanner
类在其构造函数中传递了[[System.in(in是InputStream的对象),它是一种Stream机制,因此包含输入(保持)缓冲区。在控制台窗口中键入任何内容后,它将放置在输入缓冲区中,直到任何next ...()方法读取该缓冲区为止。[并非[全部
] >>扫描器类方法,例如next(t),nextInt(),nextDouble()等,完全利用了流输入中包含的所有内容例如,在缓冲区中,当按下ENTER键时,这些方法不会占用空格,制表符和任何换行符。但是,nextLine()方法确实消耗了输入缓冲区中的所有内容。 这就是为什么当您提示用户提供整数值(age)并使用nextInt()方法获取该数据,然后直接在后缀中提示您输入类似用户字符串的原因使用nextLine()
方法命名,您会注意到nextLine()提示被跳过。这是因为nextInt()方法没有使用输入缓冲区中的换行符,现在强制nextLine()方法使用它。在先前的nextInt()方法中完成的ENTER现在被传递到nextLine()方法中,从而给人的印象是,在实际中确实收到换行符(在大多数情况下几乎没有用。要克服这种特殊情况,最简单的方法是在scanner.nextLine();
调用之后直接添加int myVar = scanner.nextInt();
,以消耗ENTER键换行符。然后在String name = scanner.nextLine();
开始播放之前清空输入缓冲区。