Svitlana Pashkova
Svitlana Pashkova

Reputation: 11

While loop ends before checking input

It's been four days now and me being beginner I am I cant seem to make this work. So, so far my program would ask for user name and look for a match in a file I opened. If match found, it'll ask for userpassword and if userpassword is found in the file, it'll check username, password and if there is specific word on the line along with credentials, it'll open a credentials file. So I have my code working if username entered correctly the first time, it asks for the password and either breaks or lets the user to see the file. That works perfectly.

But if username is incorrect on the first try, it never checks if the second time is correct. It just ends it after 2 attempts (which is supposed to be 3 failed attempts). So here's my code

public static void main(String[] args)throws Exception {    
        Scanner scnr = new Scanner(System.in);
        //open credentials file
        FileInputStream in = new FileInputStream ("./credentials.txt");
        Scanner credentials = new Scanner(in);

         // open zookeeper file
        FileInputStream in1 = new FileInputStream ("./zookeeper.txt");
        Scanner zookeeperInfo = new Scanner(in1);

        FileInputStream in2 = new FileInputStream ("./admin.txt");
        Scanner adminInfo = new Scanner(in2);

        FileInputStream in3 = new FileInputStream ("./veterinarian.txt");
        Scanner vetInfo = new Scanner(in3);

        String userName     = "";
        String userPassword = "";
        String original     = ""; 
        int numAttempts = 0;
        boolean run = true;
        while (run) {        
          System.out.println ("User Name or Q: ");
          userName = scnr.nextLine();

          if (userName.equals("Q") || numAttempts > 3) {
            run = false;
            System.out.println("Goodbye..");
          }

          else {
            while(credentials.hasNextLine()) {
              String line = credentials.nextLine();

              if (line.contains(userName)) {
                System.out.println(userName);
                System.out.println("Gimme the password: ");
                userPassword = scnr.nextLine();
                original = userPassword;

                MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(original.getBytes());
                byte[] digest = md.digest();
                StringBuffer sb = new StringBuffer();
                for (byte b : digest) {
                  sb.append(String.format("%02x", b & 0xff));
                }

                if (line.contains(userName) && line.contains(sb.toString()) && line.contains("zookeeper")) {
                  while (zookeeperInfo.hasNextLine()) {
                    System.out.println(zookeeperInfo.nextLine() + " ");
                  }
                  break;
                }
                else if (line.contains(userName) && line.contains(sb.toString()) && line.contains("admin")) {
                  while (adminInfo.hasNextLine()) {
                    System.out.println(adminInfo.nextLine()+ " ");
                  }
                  break;
                }
                else if (line.contains(userName) && line.contains(sb.toString()) && line.contains("veterinarian")) {
                  while (vetInfo.hasNextLine()) {
                    System.out.println(vetInfo.nextLine() + " ");
                  }
                  break;
                }                                
              }                                                         
            }

Picture of working part of the code Picture of non-working part

I really don't know. I feel like I am not even doing it correctly but all my tries end right here. I have to submit it by Sunday and after the whole week nothing works.. Please help, any advice will be greatly appreciated!

Upvotes: 1

Views: 97

Answers (2)

Dilip Baluguri
Dilip Baluguri

Reputation: 81

As per the code, you posted, your code should be in infinite loop as you are not incrementing numAttempts anywhere unless user inputs 'Q' for a username. The reason why your code is not checking for username on second attempt is you are reading the whole file on one attempt when username doesn't exist in the file.

I am not sure what your requirements are but if you have read the file for every user input you will have to reread the file for every user input or store them in memory on hashmap for better performance.

else {
     FileInputStream in = new FileInputStream("./credentials.txt");
     Scanner credentials = new Scanner(in);

    while (credentials.hasNextLine()) {
        .....
   }
}

I would highly recommend reading usernames to in-memory if you have process the file for each user input.

Hope this helps. I can provide you better code if you post your reqirments.

Upvotes: 1

tkint
tkint

Reputation: 331

Besides your code is not easy to read, I made something for you, that you might use:

public static void main(String[] args) throws Exception {
    Scanner userInput = new Scanner(System.in);

    File file = new File("credentials.txt");
    FileInputStream inputStream;

    Scanner credentialsScanner;

    File infosFile;
    Scanner infoScanner = null;
    FileInputStream infosInputStream;

    boolean run = true;
    int attempts = 0;

    String username;
    String password;
    String line;

    while (run) {
        System.out.println("Give username:");
        username = userInput.nextLine();

        if (username.equals("Q") || attempts > 3) {
            run = false;
        } else {
            inputStream = new FileInputStream(file);
            credentialsScanner = new Scanner(inputStream);
            while (credentialsScanner.hasNextLine()) {
                line = credentialsScanner.nextLine();
                System.out.println(line);
                if (line.contains(username)) {
                    System.out.println("Give password:");
                    password = userInput.nextLine();

                    MessageDigest md = MessageDigest.getInstance("MD5");
                    md.update(password.getBytes());
                    byte[] digest = md.digest();
                    StringBuffer sb = new StringBuffer();
                    for (byte b : digest) {
                        sb.append(String.format("%02x", b & 0xff));
                    }

                    if (line.contains(sb.toString())) {
                        if (line.contains("zookeeper")) {
                            infosFile = new File("zookeeperInfo.txt");
                        } else if (line.contains("admin")) {
                            infosFile = new File("adminInfo.txt");
                        } else if (line.contains("veterinarian")) {
                            infosFile = new File("vetInfo.txt");
                        }

                        infosInputStream = new FileInputStream(infosFile);
                        infoScanner = new Scanner(infosInputStream);
                        while (infoScanner != null && infoScanner.hasNextLine()) {
                            System.out.println(infoScanner.nextLine() + " ");
                        }
                        attempts = 0;
                        break;
                    }
                }
            }
            attempts++;
        }
    }
}

As you can see, I simplified a bit your code:

  • One main loop:
    • Inside it, we get the username (user input)
      • If the user input is "Q" or if it's the 4th attempt => Break the loop
      • Else => continue

And when we continue the process:

  • For each line of the credential files:
    • If it contains the given username => Ask for password

Next, comes the verification of password by using MD5 decoder. Then, if the current lin contains the decoded password, process the reading of informations in other files.

After every attempt, we increase the attempt counter, but if the process succeeds, we reset this counter and break the loop.

It may not be exactly what you came for, but it would maybe help you to improve your code and to understand a bit more some logic.

Upvotes: 1

Related Questions