Получить вход для сканера Java без улучшенного сканера - PullRequest
0 голосов
/ 30 ноября 2018

Получить значение сканера, не продвигая его - 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 через API отражения Java, чтобы попытаться фактически вернуть токен, содержащий 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 входное значение объекта с его фактическим продвижением.

1 Ответ

0 голосов
/ 30 ноября 2018

То, что вы ищете, иначе может называться функцией просмотра.

Этот ответ в другом потоке указывает, что вы можете быть обслужены путем создания класса-оболочки для Scanner, который реализует эту функцию, поскольку сам класс Scanner не реализует его.

...