Проблема бесконечного цикла с try / catch - PullRequest
0 голосов
/ 13 января 2011

У меня есть цикл while, который должен перехватывать ввод не-int и просить пользователя повторно ввести int.Однако это просто бесконечно зацикливает сообщение об ошибке.У кого-нибудь есть идея, почему он не позволяет сканеру вводить второй раз?

  while(!enteredInt)
  {
      try
      {
          locus = input.nextInt();
          enteredInt = true;
      }
      catch (Exception e)
      {
          //user didn't type an integer
          System.out.println("You didn't enter a valid number, re-enter point where you will build your city");
      }
  }

Ответы [ 2 ]

9 голосов
/ 13 января 2011

Когда вы вводите токен, который не является числом, вызов nextInt не перемещает сканер за пределы токена.В результате он просто читает один и тот же токен снова и снова.

Вот документация для nextInt: http://download.oracle.com/javase/6/docs/api/java/util/Scanner.html#nextInt%28%29 (хотя соответствующее поведение фактически описано в версии, которая принимает аргумент, здесь:http://download.oracle.com/javase/6/docs/api/java/util/Scanner.html#nextInt%28int%29)

Итак, чтобы дать вам быстрый пример, давайте предположим, что входная строка равна "1 2 Foo".Я добавлю X, чтобы показать, где сейчас находится сканер.Это начинается "X1 2 Foo".Затем происходит первый вызов input.nextInt().Возвращает 1, и теперь мы находимся на "1 X2 Foo".Затем происходит второй вызов input.nextInt().Возвращает 2 и теперь мы находимся на "1 2 XFoo".Затем происходит третий вызов input.nextInt().Он не возвращается, а создает исключение InputMismatchException, а также не продвигает сканер.Итак, мы все еще на "1 2 XFoo".Поэтому, когда мы называем это в четвертый или пятый раз, происходит то же самое.

Чтобы решить эту проблему, вызов input.next() будет потреблять следующий токен, каким бы он ни был.После этого вызова, в нашем примере, мы будем на "1 2 FooX".

Обратите внимание, однако, что вызов input.next() также может генерировать исключения.В частности, он может генерировать исключение IllegalStateException, если сканер закрыт (что не должно происходить в вашем коде), или исключение NoSuchElementException, если сканер достиг конца ввода (что не произойдет, если вы читаете с клавиатуры, как яПредположим, что вы).Но чтобы быть в безопасности, вы должны либо перехватить эти ошибки и выйти из цикла, либо не перехватить их и вместо этого объявить их как выброшенные вашим методом.

2 голосов
/ 13 января 2011

Как указано в документации:

Когда сканер генерирует исключение InputMismatchException, сканер не пропустит токен, вызвавший исключение, поэтому его можно получить или пропустить другим способом.

Таким образом, один и тот же (не целочисленный) токен будет продолжать выдавать исключение.

Вы можете использовать метод next () для извлечения этого токена из улова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...