В то время как цикл с методом hasNext в качестве условия продолжает генерировать исключение ArrayOutOfBounds? (Джава)

Я работаю над именем пользователя / паролем, используя графический интерфейс. Я использую цикл while с расширением hasNext() для имени файла в качестве условия для сохранения информации, содержащейся в файле, в массив, чтобы я мог сравнить входные данные пользователя с информацией, хранящейся в файле. Затем я использую оператор if для сравнения. Если есть совпадение, то программа перенаправляет пользователя на другой класс или метод, иначе она ничего не делает.

Проблема в том, что я продолжаю генерировать исключение ArrayOutOfBounds как СКОРО, поскольку оно пытается прочитать первую строку из файла.

Я добавил System.out.println(userLogin[i]), чтобы проверить, не прошел ли он весь цикл, но не должен, так как строка никогда не выводится. Я предполагаю, что он останавливается первым делом, когда попадает в цикл while. Как это исправить? Ваша помощь очень ценится. Если вы хотите, чтобы я уточнил вопрос, скажите, пожалуйста, в своем комментарии, и я буду заново редактировать свой пост, чтобы он был максимально понятным. Это мой код следующим образом:

    private class ButtonListener implements ActionListener {

    public void actionPerformed(ActionEvent e){
        String usernameInput = "";
        char passwordInput[] = {};

        if(e.getSource() == okButton){
            usernameInput = usernameTF.getText();
            passwordInput = passwordTF.getPassword();
            try{
                verifyLogin(usernameInput, passwordInput); //sends input to be verified
            }catch (IOException ed){
                JOptionPane.showMessageDialog(null, "There was a problem " +
                        "retrieving the data.");
            }
        }else if (e.getSource() == cancelButton){
            setVisible(false);
            dispose();
        }
    }

}

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

Это метод, который проверяет, есть ли у входа совпадение:

public void verifyLogin(String username, char[] password) throws IOException {
    File myFile = new File("Accounts.txt");
    Scanner inputFile = new Scanner(myFile);

        while (inputFile.hasNext()) {
            int i = 0;

            this.userLogin[i] = inputFile.next();
            System.out.println(userLogin[i]);  //says this is where the OutOfBounds occurs
            this.passLogin[i] = inputFile.nextLine();
            this.passwordCheckLogin = this.passLogin[i].toCharArray();

            if((this.userLogin[i] == username) && (this.passwordCheckLogin == password)){
                JOptionPane.showMessageDialog(null, "Access Granted");
                inputFile.close();
                break;
            }

            i++;

        }


}

Информация в файле записана следующим образом (имя пользователя слева и пароль справа):

John001 bananas
Mike001 123chocolate

Спасибо!

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

import java.util.Scanner;
import java.io.*;
import javax.swing.*;
import java.awt.event.*;


public class DeskLogin extends JFrame {

private final int WINDOW_WIDTH = 200;
private final int WINDOW_HEIGHT = 300;
private JLabel usernameLabel;
private JLabel passwordLabel;
private JButton okButton;
private JButton cancelButton;
private JTextField usernameTF;
private JPasswordField passwordTF;
private JPanel loginPanel;
private String userLogin[] = {};
private String passLogin[] = {};
private char passwordCheckLogin[] = {};



public DeskLogin(){
super("Login");
setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
buildPanel();
add(loginPanel);

}

private void buildPanel() {
usernameLabel = new JLabel("Username: ");
passwordLabel = new JLabel("Password: ");
usernameTF = new JTextField(10);
passwordTF = new JPasswordField(10);
okButton = new JButton("OK");
cancelButton = new JButton("Cancel");

loginPanel = new JPanel();

loginPanel.add(usernameLabel);
loginPanel.add(usernameTF);
loginPanel.add(passwordLabel);
loginPanel.add(passwordTF);
loginPanel.add(okButton);
loginPanel.add(cancelButton);


okButton.addActionListener(new ButtonListener());
cancelButton.addActionListener(new ButtonListener());
}

public void verifyLogin(String username, char[] password) throws IOException {
File myFile = new File("Accounts.txt");
Scanner inputFile = new Scanner(myFile);

inputFile.useDelimiter(" ");

    while (inputFile.hasNext()) {
        int i = 0;

        this.userLogin[i] = inputFile.next();
        System.out.println(userLogin[i]);
        this.passLogin[i] = inputFile.nextLine();
        this.passwordCheckLogin = this.passLogin[i].toCharArray();

        if((this.userLogin[i] == username) && (this.passwordCheckLogin == password)){
            JOptionPane.showMessageDialog(null, "Access Granted");
            inputFile.close();
            break;
        }

        i++;

    }


}

private class ButtonListener implements ActionListener {

public void actionPerformed(ActionEvent e){
    String usernameInput = "";
    char passwordInput[] = {};

    if(e.getSource() == okButton){
        usernameInput = usernameTF.getText();
        passwordInput = passwordTF.getPassword();
        try{
            verifyLogin(usernameInput, passwordInput);
        }catch (IOException ed){
            JOptionPane.showMessageDialog(null, "There was a problem " +
                    "retrieving the data.");
        }
    }else if (e.getSource() == cancelButton){
        setVisible(false);
        dispose();
    }
}

}








}

4 ответа

Как насчет того, чтобы попытаться изменить строку для чтения System.out.println(this.userLogin[i]);? Я предполагаю, что у вас есть две переменные с именем userLogin, одна из которых является локальной для этой функции (другая является переменной экземпляра). this.userLogin это не то же самое, что userLogin, Извиняюсь, если я ухожу. Без обид.

Во-первых, вам не нужен сканер. BufferedReader проще. Вы можете использовать разделение, чтобы разбить ваши слова в строке. Также обратите внимание на расположение закрытия потока (в конце). Кроме того, я перенастроил условное выражение, используя равно, а не ==. Наконец, String.valueOf, позволяющий сравнивать массив символов со строкой.

File myFile = new File("Accounts.txt");
BufferedReader inputFile = new BufferedReader(
       new InputStreamReader(new FileInputStream(myFile)));

String line;
while ((line = inputFile.readLine())!=null) {
    int i = 0;

    this.userLogin[i] = line.split(" ")[0];
    System.out.println(userLogin[i]);
    this.passLogin[i] = line.split(" ")[1];
    this.passwordCheckLogin = this.passLogin[i].toCharArray();

    if (this.userLogin[i].equals(username) 
      && String.valueOf(this.passwordCheckLogin).equals(password)){
        JOptionPane.showMessageDialog(null, "Access Granted");                
        break;
    }

    i++;    
}
inputFile.close();

У вас есть эти 3 установки как массивы, но вы никогда не используете их как массивы, и вы также никогда не используете их за пределами verifyLogin.

private String userLogin[] = {};
private String passLogin[] = {};
private char passwordCheckLogin[] = {};

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

public void verifyLogin(String username, char[] password) throws IOException {
    File myFile = new File("Accounts.txt");
    Scanner inputFile = new Scanner(myFile);
    String userLogin = null;
    String passLogin = null;
    char[] passwordCheckLogin = null;

    while (inputFile.hasNext()) {
        userLogin = inputFile.next();
        if (inputFile.hasNext()){
            passLogin = inputFile.next();
            passwordCheckLogin = passLogin.toCharArray();
        }
        else {
            //Need to alert that we have an improperly formatted Accounts.txt
            break;
        }
        if((userLogin == username) && (passwordCheckLogin == password)){
            JOptionPane.showMessageDialog(null, "Access Granted");
            inputFile.close();
            break;
        }
    }
}

Насколько я могу вам сказать, установите userLogin в массив нулевой длины и никогда не увеличивайте его:

private String userLogin[] = {};

Поэтому доступ к любому элементу userLogin должен вызвать исключение. Это на самом деле не имеет ничего общего с inputFile.next() вызов. Вы могли бы сделать изолированный userLogin[0] = null и это должно взорваться.

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

Другие вопросы по тегам