【问题标题】:While loop ends before checking inputwhile 循环在检查输入之前结束
【发布时间】:2018-08-17 19:08:48
【问题描述】:

现在已经四天了,我是初学者,我似乎无法完成这项工作。 因此,到目前为止,我的程序会询问用户名并在我打开的文件中查找匹配项。如果找到匹配项,它会询问用户密码,如果在文件中找到用户密码,它会检查用户名、密码,如果行中有特定的单词和凭据,它会打开一个凭据文件。 因此,如果用户名第一次输入正确,我的代码就可以工作,它会要求输入密码,然后中断或让用户查看文件。效果很好。

但如果用户名在第一次尝试时不正确,它永远不会检查第二次是否正确。它只是在 2 次尝试后结束(应该是 3 次失败的尝试)。 这是我的代码

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

我真的不知道。我觉得我什至没有正确地做到这一点,但我所有的尝试都到此结束。我必须在星期天之前提交它,整个星期之后没有任何效果.. 请帮助,任何建议将不胜感激!

【问题讨论】:

  • 你能把整个代码贴出来。无法确定 numAttempts 更改的位置。
  • 请阅读minimal reproducible example并相应地完善您的问题。
  • 你是否在任何地方增加numAttempts
  • 如何获得credentials 以及在哪里增加numAttempts
  • a) 你的 while 循环方式太大了。试试看罗伯特马丁的“清洁代码”! b)您的格式(缩进!)很烂,没有IDE就不可能看到'c)是整个循环吗?好像缺少很多右括号。继续。

标签: java if-statement while-loop


【解决方案1】:

除了你的代码不容易阅读之外,我为你做了一些东西,你可能会使用:

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++;
        }
    }
}

如您所见,我简化了您的代码:

  • 一个主循环:
    • 在其中,我们得到用户名(用户输入)
      • 如果用户输入的是“Q”或者是第 4 次尝试 => 打破循环
      • 否则 => 继续

当我们继续这个过程时:

  • 对于凭证文件的每一行:
    • 如果它包含给定的用户名 => 询问密码

接下来,使用MD5解码器验证密码。然后,如果当前 lin 中包含解码后的密码,则处理读取其他文件中的信息。

每次尝试后,我们都会增加尝试计数器,但如果过程成功,我们会重置此计数器并中断循环。

这可能不是你来的目的,但它可能会帮助你改进你的代码并理解更多的一些逻辑。

【讨论】:

    【解决方案2】:

    根据您发布的代码,您的代码应该处于无限循环中,因为除非用户为用户名输入“Q”,否则您不会在任何地方增加 numAttempts。您的代码在第二次尝试时未检查用户名的原因是,当文件中不存在用户名时,您正在一次尝试读取整个文件。

    我不确定您的要求是什么,但如果您已为每个用户输入读取文件,您将不得不为每个用户输入重新读取文件或将它们存储在 hashmap 的内存中以获得更好的性能。

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

    如果您为每个用户输入处理文件,我强烈建议您将用户名读取到内存中。

    希望这会有所帮助。如果您发布您的需求,我可以为您提供更好的代码。

    【讨论】:

      猜你喜欢
      • 2014-09-04
      • 2016-02-08
      • 2019-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-05
      • 1970-01-01
      • 2021-02-25
      相关资源
      最近更新 更多