Java: остановить сканер после первого токена

1

Я пытаюсь генерировать автоматизированные входы в System.in и хотел бы иметь возможность читать последующие токены в потоке различными сканерами в произвольные моменты времени:

// save System.in for later restoration
InputStream inTemp = System.in;

// create an input
String input = "15 3";
// push input into InputStream
InputStream bais = new ByteArrayInputStream(input.getBytes());
// deviate System.in
System.setIn(bais);

Scanner s1 = new Scanner(System.in);
// the nextInt should only read the "15" from the input
int i1 = s1.nextInt();
System.out.println("#1: " + i1 * 2);

Scanner s2 = new Scanner(System.in);
// the nextInt should read the "3" from the input
int i2 = s2.nextInt();
System.out.println("#2: " + i2 * 2);

// restore System.in
System.setIn(inTemp);

К сожалению, сканер s1 превентивно считывает весь контент потока вместо того, чтобы читать только первый токен. Таким образом, второй сканер s2 находит пустой ввод.

Вышеприведенный код представляет собой крайне упрощенную реальную ситуацию: часть, в которой используются сканеры, не отвечает моей ответственности. Он создается учащимися, которые представляют свои классы в нашу экзаменационную систему. Наша система вызывает методы учеников после заполнения System.in тестовыми данными. Поэтому мы не можем влиять на то, как используются сканеры. BTW: закрытие сканера не поможет. Первый сканер просто считывает слишком много данных из потока.

На самом деле, я вижу несколько возможных способов:

  1. Поместите маркеры на вход, которые не позволяют сканеру читать дальше.

  2. Расширьте ByteArrayInputStream таким образом, чтобы он показывал только один токен за попытку. Это, вероятно, означает манипулирование выводами доступных() -method, pos-атрибутов и содержимого buf Stream, а также для отслеживания количества показаний, выполняемых сканером. Тем не менее, сканер продолжает запрашивать данные, независимо от того, сколько жетонов он должен читать. Кто-нибудь сделал это раньше?

  3. Используйте другой поток, который обеспечивает функциональность, описанную под 2 (или что-то подобное).

  4. Попросите учащихся прочитать данные из Сканера с помощью другого метода (вместо nextInt), который будет вести себя так, как требуется. Есть ли такой метод? Я его не нашел.

Я уже начал манипулировать этим поведением, расширив ByteArrayInputStream, но не зашел слишком далеко, поскольку я думал, что это может быть концептуально слишком сложный подход.

Любая помощь приветствуется.

С наилучшими пожеланиями, Томас

Теги:
string
stream

2 ответа

0

Я думаю, что ответ... Нет.

Невозможно предотвратить Scanner вперед и буферизацию символов, а также не заставить его "возвращать" символы, которые он буферизует. (Действительно, если источник, который вы читали, не поддерживал методы меток/сброса или pushback, было бы невозможно "вернуть" символы.)

Вам нужно будет пересмотреть свой подход к тестированию. Повторное использование экземпляра Scanner.

Другая альтернатива - реализовать собственную версию Scanner... что позволяет вам "возвращать" буферные символы.

  • 0
    Я, вероятно, создам свою собственную версию ByteArrayInputStream таким образом, чтобы он Scanner.nextInt() только один токен на вызов Scanner.nextInt() . При этом мне не нужно менять настройку для студентов или учить их каким-то особым правилам программирования, чтобы удовлетворить наш подход к тестированию. Сложнее всего, вероятно, провести различие между Scanner читающим впереди, и Scanner читающим следующий токен.
  • 0
    Я думал об этом подходе. «Сложнее всего, вероятно, провести различие между сканером, читающим впереди, и сканером, читающим следующий токен». На самом деле. Эта часть может быть выполнена только путем изменения Scanner . НАСКОЛЬКО МНЕ ИЗВЕСТНО.
0

Попробуйте закрыть первый сканер после первого чтения. Это должно остановить первый сканер и позволить второму сканеру читать следующую переменную.

  • 0
    Это также закроет основной поток - здесь System.in - и ничто не может быть прочитано из этого потока любым методом, потому что: «Когда сканер закрыт, он закроет свой входной источник, если источник реализует интерфейс Closeable». (взято из документации Oracle Java 7 ), что делает ByteArrayInputStream .

Ещё вопросы

Сообщество Overcoder
Наверх
Меню