简体   繁体   English

使用while()循环检查元素的.txt文件

[英]Issue checking a .txt file for an element using a while() loop

I'm writing a program that asks a user to log in and checks if their ID is inside a file "Employees.txt" and if it is then it will print out VALID __ ID if they're a Manager or an Assistant. 我正在编写一个程序,要求用户登录并检查他们的ID是否在文件“Employees.txt”中,如果是,那么如果他们是经理或助理,它将打印出VALID __ ID。 But when I enter an invalid ID, say "x" in and then try again, it loops forever, not checking if the ID is valid. 但是当我输入一个无效的ID,说“x”然后再试一次,它会永远循环,而不是检查ID是否有效。 How can I fix this issue? 我该如何解决这个问题? I have Employees.txt in the same directory as Account.java and 我在与Account.java和。相同的目录中有Employees.txt

E12,Manager
E13,Assistant

is what's inside the file. 是文件里面的东西。 Any help would be appreciated as I've tried everything I could. 任何帮助都会受到赞赏,因为我已尽力而为。 Thanks. 谢谢。

import java.io.*;
import java.util.*;
public class Account
{
    public static String  accountInput;
    public static boolean inSystem      = true;
    public static boolean displayLogIn  = true;
    public static boolean managerLogIn  = false;
    public static Scanner userInput     = new Scanner(System.in);
    public static File stockFile        = new File("Stock.txt");
    public static File employeesFile    = new File("Employees.txt");
    public static File transactionsFile = new File("Transactions.txt");
    public static void main(String[] args) throws IOException
    {
        String[] contents;
        System.out.println("\tWorking Files");
        System.out.println("-------------------------------------------");
        System.out.println("Stock File:\t\tStock.txt\nEmployee File:\t\tEmployees.txt\nTransactions File:\tTransactions.txt\n\n");
        Scanner readEmployeesFile = new Scanner(employeesFile);
        while(inSystem)
        {
            while(displayLogIn)
            {
                System.out.print("Enter Employee ID(i.e E1)\tEnter Q to Quit Program.\nEnter here: ");
                accountInput = userInput.nextLine();

                while(readEmployeesFile.hasNextLine())
                {
                    contents = readEmployeesFile.nextLine().split(",");
                    if(contents[0].equals(accountInput) & contents[1].equals("Manager"))
                    {
                        displayLogIn = false;
                        System.out.print("Valid MGR ID");
                        inSystem     = false;
                    }
                    else if(contents[0].equals(accountInput) & contents[1].equals("Assistant"))
                    {
                        displayLogIn = false;
                        System.out.print("Valid AST ID");
                        inSystem     = false;
                    }
                    else if(accountInput.equals("Q"))
                    {
                        displayLogIn = false;
                        inSystem     = false;
                    }
                }
            }
        }
    }
}

When you enter an ID, you start looping on your file to see if that ID matches. 输入ID时,您开始循环文件以查看该ID是否匹配。

You reach the end of the file. 你到达文件的末尾。 readEmployeesFile.hasNextLine() is false. readEmployeesFile.hasNextLine()为false。 So you iterate again, read the next ID. 所以你再次迭代,阅读下一个ID。

But the readEmployeesFile is still at the end of the file. readEmployeesFile仍然在文件的末尾。 There is nothing that takes it back to the beginning. 没有什么可以把它带回到开头。 So when it gets to the while again, readEmployeesFile.hasNextLine() is still false. 所以,当它到达while再次, readEmployeesFile.hasNextLine() 仍然是假的。

Possible solutions: 可能的解决方案:

  • Open the scanner, readEmployeesFile , not at the beginning of the method, but right before you use it. 打开扫描程序readEmployeesFile ,而不是在方法的开头,而是在使用它之前。 Then close it right after you reach the end of the file. 然后在到达文件末尾后立即关闭它。 So you will be opening and closing it every time the user enters an ID. 因此,每次用户输入ID时,您都将打开和关闭它。
  • Read all the IDs from the file into a Map before you start prompting the user, and then look for the ID in that map instead of directly in the file. 在开始提示用户之前,将文件中的所有ID读入Map ,然后在该映射中查找ID,而不是直接在文件中查找。 This would be more efficient. 这会更有效率。

The problem is that you open the Scanner inside the loop, forcing it to read all the contents of the file on the first iteration. 问题是您在循环内打开Scanner ,强制它在第一次迭代时读取文件的所有内容。 This means that the condition in while(readEmployeesFile.hasNextLine()) will always evaluate to false after the first iteration and the loop will never be entered again. 这意味着while(readEmployeesFile.hasNextLine())中的条件在第一次迭代后将始终求值为false ,并且永远不会再次输入循环。 For this reason only the first trial may be valid, afterwards your loop cannot terminate. 因此,只有第一次试验可能有效,之后您的循环无法终止。

Here is adjusted code that worked for me: 这是调整后的代码,对我有用:

import java.io.*;
import java.util.*;
public class Account
{
    public static String  accountInput;
    public static boolean inSystem      = true;
    public static boolean displayLogIn  = true;
    public static Scanner userInput     = new Scanner(System.in);
    public static File employeesFile    = new File("Employees.txt");
    public static void main(String[] args) throws IOException
    {
        List<String[]> contents = new ArrayList<>();
        System.out.println("\tWorking Files");
        System.out.println("-------------------------------------------");
        System.out.println("Stock File:\t\tStock.txt\nEmployee File:\t\tEmployees.txt\nTransactions File:\tTransactions.txt\n\n");
        Scanner readEmployeesFile = new Scanner(employeesFile);
        while(readEmployeesFile.hasNextLine()) {
            String[] current = readEmployeesFile.nextLine().split(",");
            contents.add(current);
        }
        while(inSystem)
        {
            while(displayLogIn)
            {
                System.out.print("Enter Employee ID(i.e E1)\tEnter Q to Quit Program.\nEnter here: ");
                accountInput = userInput.nextLine();

                for(String[] content: contents) {
                    if (content[0].equals(accountInput) & content[1].equals("Manager")) {
                        displayLogIn = false;
                        System.out.print("Valid MGR ID");
                        inSystem = false;
                    } else if (content[0].equals(accountInput) & content[1].equals("Assistant")) {
                        displayLogIn = false;
                        System.out.print("Valid AST ID");
                        inSystem = false;
                    } else if (accountInput.equals("Q")) {
                        displayLogIn = false;
                        inSystem = false;
                    }
                }
            }
        }
        readEmployeesFile.close();
    }
}

As you can see, the input file is read a single time before entering the loop and stores all the lines in contents which is now of type List<String[]> . 如您所见,输入文件进入循环之前一次读取,并将所有行存储在现在为List<String[]>类型的contents中。 In the for loop you simply need to check the contents of the file that have already been read. for循环中,您只需要检查已经读取的文件的内容。

On a side note, you should always close the resources that you are using. 另外,您应该始终关闭正在使用的资源。 In this case I refer to the Scanner object and this is why I included the line readEmployeesFile.close(); 在这种情况下,我指的是Scanner对象,这就是我包含readEmployeesFile.close();行的readEmployeesFile.close(); after your loop. 循环之后。

Change 更改

contents[0].equals(accountInput) & contents[1].equals("Manager")
contents[0].equals(accountInput) & contents[1].equals("Assistant")

to

contents[0].equals(accountInput) && contents[1].equals("Manager")
contents[0].equals(accountInput) && contents[1].equals("Assistant")

The AND operator is represented with a double ampersand (&&), not one. AND运算符用双符号(&&)表示,而不是一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM