简体   繁体   English

从文件中搜索字符串,并在 java 中返回该字符串?

[英]Searching for a string from file, and returning that string in java?

I'm still fairly new to Java but I've been trying to have my program have the user enter a name and to search for that name in a file and if that name is in the file, it will get returned to main.我对 Java 还是很陌生,但我一直在尝试让我的程序让用户输入一个名称并在文件中搜索该名称,如果该名称在文件中,它将返回到 main。 If that name isn't in the file, the program will ask the user to enter another name until they enter a name that is in the file.如果该名称不在文件中,程序将要求用户输入另一个名称,直到他们输入文件中的名称为止。 If the user enters 'quit' the program will exit.如果用户输入“退出”,程序将退出。 I have code that doesn't do what I'm looking for but I hope that it gets my point across..我的代码不能满足我的要求,但我希望它能让我明白我的意思..

public static String getName(File inFile, Scanner console) throws FileNotFoundException {       //Retrieves name from the user and returns it to main
    System.out.print("Enter a name (or quit): ");   
    String name = console.next();
    System.out.println();


    Scanner scanner = new Scanner(inFile);
    while (scanner.hasNextLine()) {
       String lineFromFile = scanner.nextLine();
       if(lineFromFile.contains(name)) { 
           // a match!
           System.out.println("I found " +name);
       }   

       if(name.equalsIgnoreCase("quit")){
           System.exit(0);
       }
       else{
           console.nextLine(); 
             System.out.println("That name wasn't found.");
             System.out.println("Enter a name (or quit): ");
       }

    }

    return name;
}

In the following code we have an outer loop while(!hasName) that causes the program to continually ask for a name until it finds one in your file.在下面的代码中,我们有一个外循环 while(!hasName) 使程序不断地要求一个名称,直到它在您的文件中找到一个名称。

There are improvements you can do so that you only read the file once, however that seems to be outside the scope of this question.您可以进行一些改进,以便您只读取一次文件,但这似乎超出了本问题的范围。

Try this:尝试这个:

    public static String getName(File inFile, Scanner console) throws FileNotFoundException {       //Retrieves name from the user and returns it to main
    boolean hasName = false;
while(!hasName)
{
    System.out.print("Enter a name (or quit): ");   
    String name = console.next();
    System.out.println();


    Scanner scanner = new Scanner(inFile);
    while (scanner.hasNextLine()) {
       String lineFromFile = scanner.nextLine();
       if(lineFromFile.contains(name)) { 
           // a match!
           System.out.println("I found " +name);
           hasName=true;
           break;
       }   

       if(name.equalsIgnoreCase("quit")){
           System.exit(0);
       }

    }
}
    return name;
}

Well, your loop is quite broken, first, you don't want to check if user wrote quit with each line of your file (what you currently do).好吧,你的循环很糟糕,首先,你不想检查用户是否用你的文件的每一行写了quit (你目前所做的)。 Check that before you start ro read your file in a loop.在开始之前检查是否循环读取您的文件。

Second, you don't know that your file doesn't contain name until you read and check all it's lines, just because your word isn't on first line doesn't mean it's not on second or third.其次,在您阅读并检查所有行之前,您不知道您的文件不包含name ,仅仅因为您的单词不在第一行并不意味着它不在第二行或第三行。 You need to print name not found after you read whole fine and still not found it.您需要阅读完整内容打印name not found但仍未找到它。

I know this has already got a few answers but I thought you might like one with comments to explain what is going on a bit more.我知道这已经得到了一些答案,但我想你可能会喜欢一个带有评论的答案来解释正在发生的事情。 I have also reformatted it in more common Java style.我还用更常见的 Java 风格重新格式化了它。

public static void main(String[] args) throws FileNotFoundException {
    String name = getName(new File("names.txt"), new Scanner(System.in));
}

//Retrieves name from the user and returns it to main
public static String getName(File inFile, Scanner console) throws FileNotFoundException {
    //Define these outside the loop because is slightly more efficient
    String lineFromFile;
    String name;
    Scanner scanner;

    // Infinite loop, this is okay because we can break out of it later
    while (true) {
        System.out.print("Enter a name (or quit): ");   
        name = console.nextLine().trim();
        if(name.equalsIgnoreCase("quit")) {
            /* It is generally bad form to use System.exit.
             * Just return control to main and let it finish cleanly.
            */
            return null;
        }

        /* We have to keep reopening the file for each go as scanner does not have a rewind option
         * You could use a different reader instead to solve this.
        */
        scanner = new Scanner(inFile);
        while (scanner.hasNextLine()) {
            /* Get the next line and trim any trailing spaces
             * This could give a NullPointerException but we already checked it had a next line.
            */
            lineFromFile = scanner.nextLine().trim();
            /* I assumed you were looking for an exact match
             * because otherwise e.g. Bob and Bobby look the same
             * also equalsIgnoreCase allows me to ignore the case
            */
            if(lineFromFile.equalsIgnoreCase(name)) {
                scanner.close();
                System.out.println("I found " + name);
                return name; // The return keyword lets you send something back
            }
        }
        scanner.close();
    }
}

You might also want to consider using a BufferedReader instead of a scanner, scanners are more used when you want to read bits of lines, like if you were trying to read a code file or a book.您可能还需要考虑使用 BufferedReader 而不是扫描仪,当您想要读取行的位时,更会使用扫描仪,例如您正在尝试阅读代码文件或书籍。 In particular when you want to read lots of types of data or regular expressions.特别是当您想要读取大量类型的数据或正则表达式时。 For just reading full lines of text just a buffered reader wrapping a file reader is better.对于仅阅读整行文本,仅缓冲阅读器包装文件阅读器更好。 I left this out because the scanner does work, it may be slower but I doubt speed is a concern in your case.我忽略了这一点,因为扫描仪确实可以工作,它可能会更慢,但我怀疑速度是否是您的问题。 For your reference though here is an article on how to do it.供您参考,但这里有一篇关于如何操作的文章

You could also use the try-finally block or if you are able to use at least Java 7 a try with resources block to make sure you close the scanner whatever happens.您也可以使用try-finally 块,或者如果您能够使用至少 Java 7 的try with resources 块来确保无论发生什么都关闭扫描器。 I did not include this as it was not part of your question but for larger programs these constructs are very useful and will simplify your code.我没有包括它,因为它不是您问题的一部分,但对于较大的程序,这些结构非常有用,可以简化您的代码。

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

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