2015-02-22 3 views
0

Я недавно начал читать на try/catch и понимаю их в определенной степени, поэтому я подумал, что дам попробовать.Попытка/Лови прыгающие петли?

Программа, которую я пишу, запрашивает у вас двойную и сохраняет ее в массиве, но если вход не является двойным, он говорит «введите двойной», но если вы вводите не двойное число более чем один раз, тогда программа завершение и добавление всех введенных двойных значений.

Если я вхожу позволяет просто сказать "fdsaf" в тогда я получаю

Пожалуйста, введите двойной

Пожалуйста, введите двойную

Пожалуйста, введите двойной

0,0

package task4;

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

public class DataReader { 

public static void main(String[] args) { 
    // TODO Auto-generated method stub 

    ArrayList<Double> fPoint = new ArrayList<Double>(); 
    double holder = 0; 

    Scanner in = new Scanner(System.in); 
    int i = 0; 

    while(i < 2){ 
     try{ 
     System.out.println("Please input an double"); 

     double temp = in.nextDouble();  
     fPoint.add(temp); 

    }catch(InputMismatchException e){ 
     System.out.println("Please input a double"); 
     i++; 
    } 
} 

    for(int j = 0; j < fPoint.size(); j++){ 
     holder += fPoint.get(j); 
    } 
    System.out.println(holder); 
} 

} 
+4

В чем вопрос? – RealSkeptic

+0

Ну, если я вхожу в 'sdjgf', тогда цикл петли будет повторяться во второй раз, у пользователя должен быть второй шанс ввести двойной @RealSkeptic –

ответ

0

Ошибка использования вашей программы API Scanner. Пожалуйста, внимательно прочитайте его документацию. Я укажу одну важную фразу:

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

Все, что вы делаете в этом случае снова вызывается метод же, что приводит к бесконечному циклу. Как правило, вы хотите позвонить по телефону

in.nextLine(); 

в блоке catch.

0

Ваша проблема не столько в try...catch, сколько и в том, как работает Scanner.

Scanner держит вокруг «смотреть вперед» буфер, который позволяет ему иметь методы, как hasNextInt(), hasNextDouble() и т.д.

Когда один из его методов, как nextDouble(), называется он считывает входные данные от своего источника (System.in) в этом случае в этот буфер «смотреть вперед» и проверяет, совместима ли она с запросом пользователя. Если нет, вход остается в буфере, а Scanner выдает исключение. (Если метод был hasNextDouble(), то он не будет генерировать исключение, просто верните false).

Это может быть полезно в некоторых ситуациях. Например, если программист хочет сначала попробовать, чтобы увидеть, является ли следующий элемент во вводе int, тогда, если это не так, чтобы увидеть, является ли он двойным, а если нет, чтобы увидеть, является ли строка строкой, которая соответствует некоторому шаблону - программист может это сделать, потому что данные все еще ждут в этом буфере и не будут выбрасываться, пока он не будет правильно прочитан каким-либо способом nextXXX().

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

Каждый раз, когда вы звоните nextDouble(), он смотрит на этот буфер, который не изменился, и видит, что это еще не двойной, и он держит его там и бросает исключение снова. Ваш i увеличивается, вы достигаете 2, и вы выходите из своей программы, хотя вы только пробовали один элемент ввода.

Итак, как вам сказали, вы не очищаете буфер до повторной попытки. Для этого вы можете использовать nextLine(). Поскольку он не ожидает какого-либо конкретного ввода и ничего не примет, он, безусловно, удалит этот плохой ввод из буфера. Фактически, он удалит все до конца строки ввода.

Поместите его в свой блок catch. Как только вы это сделаете, ваш цикл будет работать правильно, читая ваш следующий реальный вход.