Java 输入错误类型时,如何防止扫描仪抛出异常?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2496239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I keep a Scanner from throwing exceptions when the wrong type is entered?
提问by David
Here's some sample code:
这是一些示例代码:
import java.util.Scanner;
class In
{
public static void main (String[]arg)
{
Scanner in = new Scanner (System.in) ;
System.out.println ("how many are invading?") ;
int a = in.nextInt() ;
System.out.println (a) ;
}
}
If I run the program and give it an int
like 4
, then everything goes fine.
如果我运行程序并给它一个int
赞4
,那么一切都会顺利。
On the other hand, if I answer too many
it doesn't laugh at my funny joke. Instead I get this(as expected):
另一方面,如果我回答,too many
它不会嘲笑我的笑话。相反,我得到了这个(正如预期的那样):
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:819)
at java.util.Scanner.next(Scanner.java:1431)
at java.util.Scanner.nextInt(Scanner.java:2040)
at java.util.Scanner.nextInt(Scanner.java:2000)
at In.main(In.java:9)
Is there a way to make it ignore entries that aren't ints or re prompt with "How many are invading?" I'd like to know how to do both of these.
有没有办法让它忽略不是整数的条目或重新提示“有多少人正在入侵?” 我想知道如何做到这两点。
采纳答案by polygenelubricants
You can use one of the many hasNext*
methods that Scanner
has for pre-validation.
您可以使用具有预验证的众多hasNext*
方法之一Scanner
。
if (in.hasNextInt()) {
int a = in.nextInt() ;
System.out.println(a);
} else {
System.out.println("Sorry, couldn't understand you!");
}
This prevents InputMismatchException
from even being thrown, because you always make sure that it WILLmatch before you read it.
这可以防止InputMismatchException
从甚至被抛出,因为你总是确保它WILL你读它之前匹配。
java.util.Scanner API
java.util.Scanner API
boolean hasNextInt()
: Returnstrue
if the next token in this scanner's input can be interpreted as an int value in the default radix using thenextInt()
method. The scanner does not advance past any input.String nextLine()
: Advances this scanner past the current lineand returns the input that was skipped.
boolean hasNextInt()
:返回true
此扫描器输入中的下一个标记是否可以使用该nextInt()
方法解释为默认基数中的 int 值。扫描仪不会通过任何输入。String nextLine()
:将此扫描器推进到当前行并返回被跳过的输入。
Do keep in mind the sections in bold. hasNextInt()
doesn't advance past any input. If it returns true
, you can advance the scanner by calling nextInt()
, which will not throw an InputMismatchException
.
请记住以粗体显示的部分。hasNextInt()
不会超过任何输入。如果它返回true
,您可以通过调用来推进扫描器nextInt()
,这不会抛出InputMismatchException
.
If it returns false
, then you need to skip past the "garbage". The easiest way to do this is just by calling nextLine()
, probably twice but at least once.
如果它返回false
,那么你需要跳过“垃圾”。最简单的方法是调用nextLine()
,可能两次,但至少一次。
Why you may need to do nextLine()
twice is the following: suppose this is the input entered:
您可能需要执行nextLine()
两次的原因如下:假设这是输入的输入:
42[enter]
too many![enter]
0[enter]
Let's say the scanner is at the beginning of that input.
假设扫描仪位于该输入的开头。
hasNextInt()
is true,nextInt()
returns42
; scanner is now at just beforethe first[enter]
.hasNextInt()
is false,nextLine()
returns an empty string, a secondnextLine()
returns"too many!"
; scanner is now at just afterthe second[enter]
.hasNextInt()
is true,nextInt()
returns0
; scanner is now at just beforethe third[enter]
.
hasNextInt()
为真,nextInt()
返回42
;扫描仪现在就在第一次之前[enter]
。hasNextInt()
为假,nextLine()
返回一个空字符串,第二个nextLine()
返回"too many!"
;扫描仪现在是刚过第二[enter]
。hasNextInt()
为真,nextInt()
返回0
;扫描仪现在就在第三个之前[enter]
。
Here's an example of putting some of these things together. You can experiment with it to study how Scanner
works.
这是将其中一些东西放在一起的示例。您可以尝试使用它来研究Scanner
工作原理。
Scanner in = new Scanner (System.in) ;
System.out.println("Age?");
while (!in.hasNextInt()) {
in.next(); // What happens if you use nextLine() instead?
}
int age = in.nextInt();
in.nextLine(); // What happens if you remove this statement?
System.out.println("Name?");
String name = in.nextLine();
System.out.format("[%s] is %d years old", name, age);
Let's say the input is:
假设输入是:
He is probably close to 100 now...[enter]
Elvis, of course[enter]
Then the last line of the output is:
然后输出的最后一行是:
[Elvis, of course] is 100 years old
回答by Anthony Forloney
It's always a benefit to haveyour application throw an error when an error occurs opposed to ways to keepit from happening.
当错误发生时让你的应用程序抛出错误总是有好处的,而不是阻止它发生的方法。
One alternative is to wrap the code inside a try {...}
catch {...}
block for InputMismatchException
.
You might also want to wrap the code inside a while
loop to have the Scanner
keep prompting until a specific condition is met.
一个替代方案是包装一个内的代码try {...}
catch {...}
块InputMismatchException
。您可能还想将代码包装在一个while
循环中,以便在Scanner
满足特定条件之前一直提示。
回答by Bill K
In general I really, really dislike using the same library call for both reading and parsing. Language libraries seem to be very inflexible and often just can't be bent to your will.
总的来说,我真的非常不喜欢使用相同的库调用来读取和解析。语言库似乎非常不灵活,而且通常不能屈从于您的意愿。
The first step that pulls data from System.in should not be able to fail, so have it read it as a string into a variable, then convert that string variable to an int. If the conversion fails, great--print your error and continue.
从 System.in 中提取数据的第一步应该不会失败,因此将其作为字符串读取到变量中,然后将该字符串变量转换为 int。如果转换失败,那就太好了——打印您的错误并继续。
When you wrap your stream with something that can throw an exception, it gets kind of confusing just what state the whole mess leaves your stream in.
当你用一些可以抛出异常的东西包装你的流时,它会让人困惑整个混乱让你的流处于什么状态。