[英]I can't see why my scanner in java is throwing a “NoSuchElementException”
We need to make something of a lexical analyzer, and I have had some trouble with a particular function of mine, useLoad, or more accurately, what happens in Main after useLoad is used. 我们需要创建一个词法分析器,并且我在使用我的特定函数时遇到了一些问题,使用了载荷,或者更准确地说,在使用useLoad之后在Main中发生了什么。
I figured out that that was because...for some reason, buffer=keyboard.nextLine()
is throwing the error, because it's not getting more input from the keyboard for some reason. 我发现那是因为......出于某种原因,
buffer=keyboard.nextLine()
抛出了错误,因为由于某种原因它没有从键盘获得更多的输入。 I thought that .nextLine() should force it to get more input from the user. 我认为.nextLine()应该强制它从用户那里获得更多的输入。 And I don't know why it's throwing that exception specifically after this one particular method.
而且我不知道为什么它会在这个特定方法之后特别抛出异常。 It can do other methods just fine and not lose its ability to read.
它可以做其他方法就好并且不会失去阅读能力。 Is it because I have a variable called keyboard in another object and closed it?
是因为我在另一个对象中有一个名为keyboard的变量并将其关闭吗? That seems doubtful.
这似乎令人怀疑。 Just tried changing the name.
刚刚尝试更改名称。 Didn't make a difference.
没有什么区别。
Variables used but not declared in the below code: Keywords[0] is the String "load ". 使用但未在以下代码中声明的变量:关键字[0]是字符串“load”。 initial = the scanner string that's passed in to the function.
initial =传递给函数的扫描程序字符串。 offset = a counter variable, to see how far in to the line we've read.
offset =一个计数器变量,看看我们读到的行的距离。
The useLoad function (which is what I think is messing up somehow), is at the bottom, but I included everything it runs through (with each method separated by a horizontal rule), in chronological order, just in case I'm just not seeing what's going on. useLoad函数(我认为这是某种方式搞乱)位于底部,但我按时间顺序包含了它运行的所有内容(每个方法用水平规则分隔),以防万一我不是看看发生了什么。
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in); //the scanner for keyboard
int i = 0;
String buffer ="";
boolean loopControl == true;
SymbolTable mySym = new SymbolTable();
System.out.println("READY FOR INPUT\n");
while (loopControl == true){
//read in the line
buffer = "";
buffer = keyboard.nextLine();
if(!mySym.checkStop(buffer)){ //if we didn't stop
mySym.primary(buffer);
}
else{//if we did stop
closeLoop();
}
if (i >= 55){
loopControl = false;
System.out.println(("You have gone over the limit ("+i+" lines) per execution. Please continue by running this program again.").toUpperCase());
//just a safety precaution...you know... in case closeLoop doesn't work
}
i++;
}
keyboard.close();
}
if(initial.substring(0, Keywords[0].length()).equals(Keywords[0])){ //Load
//if this is working as expected, then we simply need to do what the keyword says to do.
offset += Keywords[0].length(); //we have moved this much deeper in to the line
useLoad(offset, initial);
offset = 0; //just make sure, once we are done with the line, we start back at the start of the next line.
return; //we found what we were looking for, get out.
}
private void useLoad(int offsetIn, String readIn) {
double doubIn = 0;
//now get the value of the
Scanner keyboard = new Scanner(System.in); //the scanner for keyboard
System.out.println("\nENTER VALUE FOR " + readIn.toUpperCase());
doubIn = keyboard.nextDouble();
keyboard.close();
variables.create(readIn.substring(offsetIn), doubIn);
}
You close the keyboard
each time round the loop. 每次绕循环关闭
keyboard
。 Therefore the second time around you read from a closed keyboard
object. 因此第二次你从一个封闭的
keyboard
对象中读取。
A quick look at the documentation for Scanner.nextLine
contains the news that it might throw: 快速浏览
Scanner.nextLine
的文档包含它可能抛出的新闻:
NoSuchElementException - if no line was found
I think I've figured out your problem. 我想我已经找到了你的问题。
Java docs for both Java 7 and 8 include this line in Scanner's close method documentation: Java 7和Java 8的Java文档在Scanner的close方法文档中包含了这一行:
If this scanner has not yet been closed then if its underlying readable also implements the
Closeable
interface then the readable'sclose
method will be invoked.如果此扫描程序尚未关闭,那么如果其底层可读也实现了
Closeable
接口,则将调用可读的close
方法。
Looking into the docs for System, I've found that System.in is of type InputStream
which, you guessed it, implements Closeable
. 查看System的文档,我发现System.in是
InputStream
类型,你猜对了,它实现了Closeable
。 The close
method documentation for InputStream
says that it does nothing; InputStream
的close
方法文档说它什么都不做; however, InputStream
is abstract
and close
is not marked as final
, which means it can be overridden. 但是,
InputStream
是abstract
, close
不会标记为final
,这意味着它可以被覆盖。 System.in
returns an InputStream
which could potentially - and clearly does - do something. System.in
返回一个可能 - 而且显然确实 - 做某事的InputStream
。
So the problem is, you are creating multiple Scanner
s with System.in
, and each time you close any one of them , you close System.in
, rendering it useless! 所以问题是,你正在用
System.in
创建多个Scanner
,每次你关闭其中任何一个 ,你关闭System.in
,使它无用!
This problem has actually been discussed in another question here , with a solution given. 这个问题实际上已经在另外一个问题讨论在这里 ,给定的解决方案。 That said, for your program I would suggest one of two approaches:
也就是说,对于您的计划,我建议采用以下两种方法之一:
InputStream
in its constructor. InputStream
。 Have this class' InputStream
implementation call all the methods of its wrapped object, except for the close
method which is a no-sell, and then pass Wrapper(System.in)
to Scanner instead of System.in
directly. InputStream
实现调用其包装对象的所有方法,除了close
方法是无销售,然后直接将Wrapper(System.in)
传递给Scanner而不是System.in
。 However, I would be wary of taking this approach except in very specific circumstances, because any time you use one of these wrappers you would need to remember to close
its wrapped object at the end of its use, unless it's something like System.in
. close
它的包装对象,除非它类似于System.in
。 close
Scanner from there. close
扫描程序。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.