Попытка / перехват в цикле do-while для проверки пользовательского ввода (массива) — неправильная логическая инициализация и позиция

#java #exception #try-catch #do-while

#java #исключение #попытка-перехват #do-while

Вопрос:

Я новичок в Java, и я учусь управлять исключениями и 2D-массивами. Я выполняю упражнение для отображения в 2D-массиве результата продаж разных моделей автомобилей.

Я смешал способ обработки исключений с помощью try catch или путем создания пользовательского исключения. В пользовательском исключении у меня проблема, которую я не могу решить.

В классе продавца:

  • В строке 16 IDE сообщает мне, что переменный «правильный» инициализатор false является избыточным избыточная инициализация
  • В строке 26 IDE сообщает мне, что условие while всегда равно false . Неправильное конечное условие для цикла do while

Я хотел объявить логическое значение правильным внутри внутреннего цикла, чтобы проверить для каждого значения, был ли ввод правильным (целое число) или нет, а затем изменить значение на true в конце попытки в случае успешного синтаксического анализа. Читая комментарии из среды IDE, я понимаю, что логическое правильное значение никогда не изменяется на true, даже если я выбираю целое число, но я не понимаю почему.

 import java.util.Scanner;
public class Sellers {
    public static void main(String[] args) throws NumberArrayException {
        Scanner myObj = new Scanner(System.in);

        int nbrOfSellers = CheckInput.control("Enter the number of sellers = ");
        int nbrOfModels = CheckInput.control("Enter the number of models = ");
        int[][] sales = new int[nbrOfSellers][nbrOfModels];

        String[] nameOfSellers = Characters.construction("seller", nbrOfSellers);
        String[] nameOfModels = Characters.construction("model", nbrOfSellers);


        for(int i = 0; i < nbrOfSellers; i  ) {
            for(int j = 0; j < nbrOfModels; j  ) {
                boolean correct = false;
                System.out.print("Enter the sales for the seller "   nameOfSellers[i]   " for the model "   nameOfModels[i]   " = ");
                do {
                    try {
                        String input = myObj.nextLine();
                        sales[i][j] = Integer.parseInt(input);
                        correct = true;
                    } catch (NumberFormatException e) {
                        throw new NumberArrayException();
                    }
                }while (!correct) ;
            }
        }
        for(int i = 0; i < nbrOfSellers; i  ) {
            for(int j = 0; j < nbrOfModels; j  ) {
                System.out.print(sales[i][j]   " ");
            }
            System.out.println();
        }
    }
}

import java.util.Scanner;
public class Characters {
    public static String[] construction(String character, int maxSize) {
        Scanner myObj = new Scanner(System.in);
        String[] myArray = new String[maxSize];
        for(int i = 0; i < maxSize; i  ) {
            System.out.print("Enter the name of the "   character   " ");
            myArray[i] = myObj.nextLine();
        }
        return myArray;
    }
}

import java.util.Scanner;
public class CheckInput {
    public static int control(String message) {
        boolean correct = false;
        int number = -1;
        Scanner myObj = new Scanner(System.in);
        do {
            try {
                System.out.print(message);
                String input = myObj.nextLine();
                number = Integer.parseInt(input);
                correct = true;
            } catch(NumberFormatException e) {
                System.out.println("Enter a number");
            }
        }while(!correct);

        return number;
    }
}

public class NumberArrayException extends RuntimeException {
    public NumberArrayException() {
        super();
    }
}
 

Комментарии:

1. ide считает, что correct это всегда верно.

Ответ №1:

Есть два способа завершения этого цикла выполнения во время выполнения: correct значение true или генерируется исключение.

Технически исключение может быть выдано только в двух строках над оператором correct = true . Поскольку вы запускаете NumberArrayException внутри цикла, он либо завершится из-за этого, либо correct будет установлен true.

Когда мы достигаем while (!correct) , then correct всегда имеет значение true с момента его установки. В противном случае мы бы завершили работу с исключением. Следовательно, у этого цикла никогда не бывает второй итерации.

Чтобы исправить это, вы можете просто избежать создания исключения, когда предоставленные входные данные не могут быть проанализированы. Затем цикл позволит пользователю ввести другое целое число.

 do {
    try {
        String input = myObj.nextLine();
        sales[i][j] = Integer.parseInt(input);
        correct = true;
    } catch (NumberFormatException e) {
        // output error message for the user here
    }
} while (!correct);
 

Ответ №2:

Ваш код довольно хорош и хорошо структурирован. На самом деле, вам следует сравнить источник CheckInput.control , чтобы понять, почему в нем нет упомянутых предупреждений: вы инициализируете локальную переменную correct так, как она должна быть, и в случае неверного ввода не генерируется исключение, что позволяет пользователю исправить его. Если вы создаете исключение из внутреннего do-while цикла, как в main методе, false значение correct никогда не используется.

Вы должны устранить эти предупреждения, повторно используя существующие CheckInput.control при инициализации 2D sales -массива. Также есть опечатка при создании nameOfModels nbrOfModels должно быть передано в качестве аргумента.

 String[] nameOfSellers = Characters.construction("seller", nbrOfSellers);
String[] nameOfModels = Characters.construction("model", nbrOfModels);


for(int i = 0; i < nbrOfSellers; i  ) {
    for(int j = 0; j < nbrOfModels; j  ) {
        sales[i][j] = CheckInput.control("Enter the sales for the seller "   nameOfSellers[i]   " for the model "   nameOfModels[i]   " = ");
    }
}
 

Комментарии:

1. Большое вам спасибо @Alex Rudenko, действительно, в моем коде есть опечатка для получения строкового массива nameOfModels. И большое вам спасибо за ваше исправление. На самом деле мой брат сказал мне протестировать оба метода (попробуйте … поймать и выбросить исключение, чтобы быть более знакомым с обоими, поэтому я использовал здесь другой подход, но я понимаю, что это был не лучший случай. Я создам еще одно исключение, чтобы проверить, является ли ввод отрицательным (номер автомобиля не должен :)), и там я буду использовать метод throwing. Еще раз спасибо

Ответ №3:

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

  do {
     try {
          String input = myObj.nextLine();
          sales[i][j] = Integer.parseInt(input);
          correct = true;
          } catch (NumberFormatException e) {
                System.out.println("Wrong input format. Please enter a number");
          }
 }while (!correct) ;
 

Комментарии:

1. Привет @Suvajit Patra, спасибо за ваш комментарий. Как я уже упоминал, целью было научиться управлять исключениями. Поскольку есть 2 возможности, используя try … catch или выбрасывая исключение, я хотел выполнить упражнение, используя оба, чтобы быть знакомым с ними обоими. Ваше решение похоже на try … catch, который я использовал в классе CheckInput. Я вполне доволен этим решением, но я хотел бы понять свою ошибку, чтобы иметь возможность использовать оба решения. В любом случае спасибо за ваш отзыв.