Можно ли назначить ввод от Java Scanner переменной внутри условия while l oop? - PullRequest
1 голос
/ 16 июня 2020

Например, вот так.

while ((input = kb.nextInt()) != 0) {
            if (input % 2 == 0) {
                System.out.println("even");
            } else {
                System.out.println("odd");
            }

вместо проверки только значения входной переменной внутри условия и получения числа от сканера внутри l oop, например:

while (input != 0) {
            input = kb.nextInt();
...code here...

Просто интересно, не плохая ли первая практика или что-то в этом роде.

Ответы [ 3 ]

0 голосов
/ 16 июня 2020

Ваши два образца кода не эквивалентны и делают разные вещи (вторая версия, вероятно, делает не то, что вы хотите). Вам понадобится еще один if (input != 0) внутри l oop и присвоение input перед l oop для второй версии. Перемещение присваивания в конец и дублирование его перед l oop также является жизнеспособным вариантом:

input = kb.nextInt();
while (input != 0) {
    if (input % 2 == 0) {
        System.out.println("even");
    } else {
        System.out.println("odd");
    }
    input = kb.nextInt();
}

И дублированные первая и последняя строки в этой версии, скорее всего, являются причиной довольно сложного кода . Этот тип l oop loop ((x = input()) != 0) можно увидеть во многих кодах C, но иногда он «необходим» и в Java, когда вы хотите уменьшить дублирование кода при обработке ввода. Это вызвано тем, что nextInt возвращает значение и изменяет базовое состояние.

0 голосов
/ 16 июня 2020

Использование nextInt() как части условия al oop, хотя и совершенно законно, может быть проблематичным c с точки зрения работы с ошибками, возникающими из неверного ввода . Настоящие люди, сидящие перед клавиатурой и вводящие данные (что, по-видимому, предполагает имя переменной Scanner kb, это именно то, с чем вы здесь имеете дело), ​​как известно, ненадежны с точки зрения качества ввода данных, поэтому плохо input - это то, к чему вы должны быть готовы.

nextInt() вызовет исключение InputMismatchException, если следующий доступный вход не является допустимым представлением целого числа. Чтобы поймать и обработать это исключение, вызов nextInt() должен выполняться внутри блока try. Однако, поскольку nextInt() является частью условия управления while l oop, единственный способ сделать это - заключить весь l oop в блок try:

try {
    while ((input = kb.nextInt()) != 0){
       ...
    }
} catch (InputMismatchException ime){
     ...
}

К сожалению, это означает, что любое исключение, вызванное nextInt(), уничтожит while l oop. Если вы хотите продолжить обработку пользовательского ввода после ошибки ввода, вам придется предоставить средства для повторного запуска while l oop и продолжать его до тех пор, пока не наступит «настоящий» сигнализируемый пользователем конец -входное состояние было достигнуто. Вы могли бы сделать это с помощью неуклюжего обходного пути вроде этого:

boolean keepGoing = true;
while (keepGoing){
    try {
        while ((input = kb.nextInt()) != 0) {
           ...
        }
        keepGoing = false;  
    } catch (InputMismatchException ime) {
        String junk = kb.next();
        System.out.println("Didn't understand your input: " + junk);
        System.out.println("Please type a valid integer");
    }
}

Но в зависимости от того, что делал код ... внутри l oop, это относительно простой обходной путь может быть неадекватным; вам может понадобиться что-то еще более сложное и нечитаемое.

Но, переместив вызов nextInt() из логики управления c l oop в тело l oop, вы получите значительные гибкость с точки зрения ваших вариантов восстановления после неправильного ввода. Имея nextInt() внутри тела l oop, теперь вы можете перехватить и обработать любое исключение целиком в пределах одной итерации l oop, без необходимости завершать сам l oop:

do {
    try {
        input = kb.next();
        if (input != 0) {
            ...
        }
    } catch (InputMismatchedException ime) {
        String junk = kb.next();
        System.out.println("Didn't understand your input: " + junk);
        System.out.println("Please type a valid integer");
    } 
} while (input != 0);

У вас также будет возможность полностью избежать исключения, используя hasNextInt(), чтобы убедиться, что присутствует действительный ввод, прежде чем пытаться прочитать его с помощью nextInt():

for(;;) {
    if (!kb.hasNextInt()) {
        String junk = kb.next();
        System.out.println("Didn't understand your input: " + junk);
        System.out.println("Please type a valid integer");
    } else {
        input = kb.nextInt();
        if (input == 0) {
            break;
        else {
            ...
        }
    }
}
0 голосов
/ 16 июня 2020

У второго нет входа, определенного для проверки условия input!=0, поэтому первый правильный, но если вы собираетесь использовать второй формат, я бы предложил изменить while l oop до do-while l oop.

...