简体   繁体   中英

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. 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.

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). 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. You need to print name not found after you read whole fine and still not found it.

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.

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. 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. 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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