2010-08-26 2 views
24

Таким образом, я получаю застрял этот кусок кода:Как обрабатывать бесконечный цикл, вызванный недействителен входом (InputMismatchException) с помощью сканера

import java.util.InputMismatchException; 
import java.util.Scanner; 

public class ConsoleReader { 

    Scanner reader; 

    public ConsoleReader() { 
     reader = new Scanner(System.in); 
     //reader.useDelimiter(System.getProperty("line.separator")); 
    } 

    public int readInt(String msg) { 
     int num = 0; 
     boolean loop = true; 

     while (loop) { 
      try { 
       System.out.println(msg); 
       num = reader.nextInt(); 

       loop = false; 
      } catch (InputMismatchException e) { 
       System.out.println("Invalid value!"); 
      } 
     } 
     return num; 
    } 
} 

и вот мой результат:

Вставить целое число:
Недопустимое значение!
Вставьте целое число:
Неверное значение!
...

+0

Рассмотрите возможность избавиться от цикла переменных и num и вместо этого используйте 'while (true) {try {....; return reader.nextInt(); } catch {....}} ' –

ответ

44

Согласно javadoc для сканера:

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

Это означает, что если следующая лексема не является int, он бросает InputMismatchException, но маркер остается там. Итак, на следующей итерации цикла reader.nextInt() снова считывает тот же токен и снова генерирует исключение. Вам нужно использовать его. Добавьте reader.next() в свой catch, чтобы использовать токен, который является недопустимым и должен быть отброшен.

... 
} catch (InputMismatchException e) { 
    System.out.println("Invalid value!"); 
    reader.next(); // this consumes the invalid token 
} 
+0

+1 Примечание для читателей: в зависимости от обстоятельств вы можете использовать' nextLine() 'вместо' next() ', так что вход вроде' this имеет пробелы в нем' не вызывает множественных исключений. – MarredCheese

0

То, что я сделал бы, читается во всей строке, используя Scanner.nextLine(). Затем создайте еще один сканер, который читает возвращаемую строку.

String line = reader.nextLine(); 
Scanner sc = new Scanner(line); 

Это сделает вашу функцию образца что-то вроде этого:

public int readInt(String msg) { 
     int num = 0; 
     boolean loop = true; 

     while (loop) { 
      try { 
       System.out.println(msg); 
       String line = reader.nextLine(); 
       Scanner sc = new Scanner(line); 
       num = sc.nextInt(); 
       loop = false; 
      } catch (InputMismatchException e) { 
       System.out.println("Invalid value!"); 

      } 
     } 
     return num; 
    } 

Таким образом, у вас есть один сканер, который получает входной сигнал и один, который проверяет его, так что вам не придется беспокоиться о считывающего уход если они вводят правильную форму ввода.

0

Охранник вашего while-do является переменной «loop».

Исключение, которое было создано прежде, чем ваш код достигнет назначения loop = false; Чтобы быть точным, исключение выбрано в предыдущем выражении, которое равно num = reader.nextInt();

Когда исключение выбрано, значение переменной «loop» равно «true», но ваш код перескакивает, чтобы поймать блок, а затем повторяет операцию while-do. Этот while-do никогда не остановится, потому что следующая итерация снова вызовет исключение, перепрыгивает, чтобы снова поймать блок и так далее.

Чтобы прекратить это время-до, вы должны защитить ваше время-до с другой логической вещи, такие как:

  1. Выход, когда читатель получает не-ИНТ персонажу
  2. Выход когда EOF

Это может быть сделано в блоке catch или в некоторых других строках.Но точное решение зависит от ваших требований.

0

Вы также можете попробовать это:

public int readInt(String msg) { 
     int num = 0; 
     try { 
      System.out.println(msg); 
      num = (new Scanner(System.in)).nextInt(); 
     } catch (InputMismatchException e) { 
      System.out.println("Invalid value!"); 
      num = readInt(msg); 
     } 
     return num; 
    } 
0
package nzt.nazakthul.app; 

import java.util.*; 

public class NztMainApp { 

    public static void main(String[] args) { 
    ReadNumber readObj = new ReadNumber(); 
    readObj.readNumber(); 
    } 

} 

class ReadNumber { 
int no; 

    int readNumber() { 
    Scanner number = new Scanner(System.in); 
    int no=0; 
    boolean b=true; 
    do { 

     try { 
      System.out.print("Enter a number:\t"); 
      no = number.nextInt(); 
     } catch (InputMismatchException e) { 
      System.out.println("No Number"); 
      //e.printStackTrace(); 

      b=false; 
     } 

    } 

    while (b); 
    return no; 

    } 

} 

Лично я использую BufferedReader и InputStreamReader читать строку и проверить, если это число или нет, но с помощью сканера меньше кода. Код проверяется и выполняется нормально.

Смежные вопросы