Почему мой оператор continue не перезапустит мой цикл while?

#java

#java

Вопрос:

Я пытаюсь завершить программу аутентификации для моего окончательного проекта. Я проверяю аутентификацию пользователя, если информация о пользователе не соответствует файлу учетных данных, вывод сообщает им об этом, а затем запрашивает имя пользователя и пароль при увеличении attemptCounter. Единственная часть, с которой я сталкиваюсь, — это когда я тестирую и неверная попытка, за которой следует правильная попытка, цикл while не перезапускает мою процедуру аутентификации, вместо этого он просто снова говорит о неправильном входе в систему. Почему мой оператор continue не перезапускает мою итерацию цикла while?

Я устал искать этот ответ на форуме и не вижу ничего конкретного по моей проблеме. Я также попытался переместить свой условный оператор, чтобы проверить, не находится ли он в неправильном месте для продолжения моей работы, но он ничего не исправил. Компилятор говорит, что оба моих оператора continue не нужны.

     //prompting user for username
    System.out.println("Please enter your username ("L" to logout "Q" to quit): ");
    username = scnr.nextLine();
    //evaluating if user wants to quit immediately 
    if(username.equals("Q")) {
        System.exit(0);
    }
    //prompting user for password and storing to password field
    System.out.println("Please enter your password: ");
    password = scnr.nextLine();
    System.out.print("n");

    //while loop that contains the authentication and authorization logic 
    while (!username.equals("Q") amp;amp; attemptCounter < 2){
        //calling of hashInput method of MD5Hash class to return the hashed user password
        userHashedPassword = userHash.hashInput(password);
        //while loop to open the credentials for authentication comparison
        while (cfScnr.hasNextLine()) {
            //assigning the files scanned next line to a field for comparison
            line = cfScnr.nextLine();
            //conditional statement to determine if username and password are contained on the line
            //will break file loop as soon as line contains the user's username and password
            //statement logic used to return the role string and remove extra characters and white space
            if (line.contains(username) amp;amp; line.contains(userHashedPassword)) {
                dqLocation = line.lastIndexOf('"');
                role = line.substring(dqLocation);
                role = role.replaceAll("\s ", "");
                role = role.replace(""", "");
                break;
            }
        }
        //conditional statement used to determine if previous loops condtional statement was meant
        //if it wasn't this condition will inform the user of incorrect username and/or password
        //inform them of attempts remaining and prompt them for a new username and password while
        //tracking the attempts and it they want to quit. If Q isn't entered main while loop will restart authentication
        if (role == null){
            attemptCounter  ;
            System.out.println("Username or password incorrect. "   (3 - attemptCounter)   " attempts remaining.");
            System.out.println("Please enter your username ("L" to logout "Q" to quit): ");
            username = scnr.nextLine();
            if(username.equals("Q")) {
                System.exit(0);
            }
            System.out.println("Please enter your password: ");
            password = scnr.nextLine();
            continue;
            }
        //this conditional statement runs only when the user is authenticated
        else {
            //creating new file object and scanner object to scan the role file
            File rFile = new File("src\zooauthenticationsystem\"   role   ".txt");
            Scanner rfScnr = new Scanner(rFile);
            //while loop to parse through the role file and output the lines of the file to the console
            while (rfScnr.hasNextLine()){
                rolePrint = rfScnr.nextLine();
                System.out.println(rolePrint);
            }
            //prompting user if they would like to logout or simply quit the program
            System.out.println("nPress "L" to logout and "Q" to quit.");
            userDecision = scnr.nextLine();
            //conditional statement to determine their input, and resetting role to null to reset authentication loop conditional statements, restarts main while loop
            if (userDecision.equals("L")){
                System.out.println("Please enter your username: ");
                username = scnr.nextLine();
                if(username.equals("Q")) {
                    System.exit(0);
                }
                System.out.println("Please enter your password: ");
                password = scnr.nextLine();
                System.out.print("n");
                role = null;
                continue;
            }
 

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

1. Ваш компилятор прав. Наметьте свой поток кода на бумаге, чтобы увидеть.

2. Я написал это из предварительно отображенного псевдокода, я не вижу, чем он отличается.

3. Где это отличается от чего именно?

4. Где он отличается от отображенной версии. Кроме того, я не понимаю, как оператор IF не встроен в правильное while, чтобы оператор continue не перезапускал текущую итерацию.

5. Опять же, наметьте свои структуры управления, чтобы увидеть, что ваши операторы continue в лучшем случае не нужны, а в худшем случае сбивают с толку. Пожалуйста, посмотрите, что я имею в виду ниже.

Ответ №1:

Давайте избавимся от большей части вашего кода, давайте лучше отформатируем код и оставим только управляющие структуры, чтобы увидеть, что continue делают операторы:

 while (!username.equals("Q") amp;amp; attemptCounter < 2) {
    userHashedPassword = userHash.hashInput(password);
    while (cfScnr.hasNextLine()) {
        line = cfScnr.nextLine();
        if (line.contains(username) amp;amp; line.contains(userHashedPassword)) {
            // ... do some stuff
            break;
        }
    }
    if (role == null) {
        // ... do some stuff
        continue;  // **** (A) ****
    } else {
        // ... do some stuff
        if (userDecision.equals("L")){
            // ... do some stuff
            continue;  // **** (B) ****
        }
    }
}
 

Если строка (A) достигнута, вы находитесь в if (roll == null) блоке, else никогда не будет введен, и цикл while будет повторяться независимо от того, что оператор continue делает continue ненужным и отвлекающим.

Аналогично, если строка (B) достигнута, вы находитесь в последнем блоке управления цикла while, и поэтому цикл будет продолжаться независимо от того, что оператор continue делает continue ненужным и отвлекающим.

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

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

2. @AaronSanchez: Вы запускали программу с помощью отладчика вашей IDE? Посмотрите, что он делает на каждом шаге, какие значения содержит каждое поле, чтобы понять, почему он ведет себя не так, как вы ожидаете или хотите. Это то, что вы должны делать, и это можете сделать только вы, поскольку у вас есть исполняемый код.

3. спасибо за вашу помощь. необходимо было перенести мой файловый объект внутрь цикла, и я также забыл сбросить счетчик попыток на 0 после обработки выхода из системы. Первый пропускал мой цикл чтения файла, а второй выходил из цикла, даже если был обработан правильный вход в систему, потому что счетчик попыток увеличивался после неудачных входов в систему. Теперь все работает так, как нужно, еще раз большое спасибо за помощь!