【问题标题】:Get Java Scanner Input Without Advancing Scanner获取 Java 扫描器输入而不使用高级扫描器
【发布时间】:2018-11-30 16:23:06
【问题描述】:

不进则出扫描器的价值——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 的输入而不推进它。

到目前为止我所做的尝试

我已经在Scanner上浏览了hasNext()的实现细节。

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 方法获得扫描仪的输入,但我真的不明白它是如何工作的。我不知道该方法是否单独获得扫描仪的值而不推进它,或者如果它推进它然后其他东西将它恢复到它在输入之前的状态,就好像它根本没有推进一样,或者如果它将它与其他东西结合起来,或者根本没有。

我一直在尝试通过 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 对象的输入值并实际推进它。

【问题讨论】:

标签: java input reflection token java.util.scanner


【解决方案1】:

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

This answer 在另一个线程上表示您可能会通过围绕实现此功能的 Scanner 创建一个包装类来为您服务,因为 Scanner 类本身不实现它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多