在不推进扫描仪的情况下获取Java扫描仪输入



在不推进的情况下获取扫描仪的值-Java

我想在不推进的情况下获得扫描仪中输入的值。目前,我使用的扫描仪输入为System.in

final var sc = new Scanner(System.in);

我知道扫描仪上的hasNext方法,它们是我目前最好/唯一的方法,可以在不推进的情况下检查其输入

以下是我如何确保来自sc的正积分输入。

public static int getPositiveIntegerInput(Scanner sc) {
System.out.println("Please input a positive integer");
sc.useDelimiter("n");
while (!sc.hasNextInt() || sc.hasNext(".*[^\d].*")) {
System.out.println("Invalid input, please try again");
sc.nextLine();
}
return sc.nextInt();
}

我想把这种不提前检查sc的输入的概念扩展到不提前实际获取sc的输入

到目前为止,我所做的努力

我已经详细介绍了hasNext()Scanner上的实现细节。

hasNext的实施:

public final class Scanner {
public boolean hasNext(Pattern pattern) {
ensureOpen();
if (pattern == null)
throw new NullPointerException();
hasNextPattern = null;
saveState();
modCount++;
while (true) {
if (getCompleteTokenInBuffer(pattern) != null) {
matchValid = true;
cacheResult();
return revertState(true);
}
if (needInput)
readInput();
else
return revertState(false);
}
}
}

至少在我看来,可以从方法getCompleteTokenInBuffer获得扫描仪的输入,但我真的不明白它是如何工作的。我不知道这个方法是在没有推进的情况下单独获得scanner的值,还是它推进了它,然后其他东西将它恢复到输入前的状态,就好像它根本没有推进一样,或者它是与其他东西结合获得的,或者真的是如何实现的。

我一直在通过Java的反射API调用私有方法Scanner,试图在不实际推进方法的情况下实际返回持有sc输入值的令牌(但老实说,我只是在玩它,不知道如何实际完成我想做的事情(。

public static void main(String[] args) {
final var sc = new Scanner(System.in);
sc.useDelimiter("n");
var str = "";
try {
Method method = Scanner.class.getDeclaredMethod("getCompleteTokenInBuffer", Pattern.class);
method.setAccessible(true);
str = (String) method.invoke(sc, Pattern.compile(".*"));
} catch (Exception e) {
System.out.println("Well, that didn't work!");
System.out.println("Exception: " + e);
}
System.out.println("getCompleteTokenInBuffer: " + str);
// Prints: "getCompleteTokenInBuffer: null"
}

注意:上面的方法在获取sc的输入值之前不等待输入,因此返回null的值。

目标:

只是重申一下,我想通过实际推进来捕获并返回Scanner对象的输入值

您要查找的内容可能会被称为peek函数。

另一个线程上的这个答案表明,您可能会通过围绕Scanner创建一个实现该功能的包装类来获得服务,因为Scanner类本身并没有实现它

最新更新