Search code examples
javafiletry-catchjava.util.scanner

How to find a specific series of inputs in a file and print out results


I'm trying to create something that's basically a way for me to search for a certain persons results on another test without having to scroll through everything. It takes inputs, such as the name, age, and gender of whatever "student" I need to find, then it's supposed to find that exact student and print the results underneath.

I have the file set up so that when someone takes the test, their results are printed like so:

Name
Age
Gender
Results

I want my code to find the name that's inputted, then see if the age underneath the name matches the input, then see if the gender underneath that matches the input. If all of these are correct, it should print out the results.

                    //These ask for the name, age, and gender

                    Scanner enterName = new Scanner(System.in);
                    System.out.println("Please enter Student's full name below.");
                    var stuName = enterName.nextLine();

                    Scanner enterAge = new Scanner(System.in);
                    System.out.println("Please enter Student's age below.");
                    var stuAge = enterAge.nextInt();

                    Scanner enterGender = new Scanner(System.in);
                    System.out.println("Please enter Student's gender below (Female or Male).");
                    var stuGender = enterGender.nextLine();


//These scanners search for the information
                    Scanner usersName = new Scanner(new File("Example.txt"));
                    Scanner usersAge = new Scanner(new File("Example.txt"));
                    Scanner usersGender = new Scanner(new File("Example.txt"));
                    Scanner usersScore = new Scanner(new File("Example.txt"));
                    var searchName = usersName.nextLine();
//This shoulder search for the information and come back true if it's found
                    try {
                              while (usersName.hasNextLine()) {
                                        searchName = usersName.nextLine();
                                        if (searchName.equals(stuName)) {
                                                  break;
                                        }
                              }

                    } catch (Exception e) {
                              if (!usersName.equals(stuName)) {
                                        System.out.println("Student not found");
                              }
                    }

                    var searchAge = usersName.nextLine();
                    if(!searchAge.equals(stuAge)) {
                              System.out.println("Student not found");
                              System.exit(1);
                    }
                    var searchGen = usersGender.nextLine();
                    if(!searchGen.equals(stuGender)) {
                              System.out.println("Student not found");
                              System.exit(1);
                    }
                    if(searchName.equals(stuName) && usersAge.equals (stuAge) && usersGender.equals(stuGender)) {
                              var searchScore = usersScore.nextDouble();
                              System.out.println("The student " + stuName + "'s score was: " + searchScore);
                              System.exit(1);
                    } else {
                              System.out.println("Student not found");
                              System.exit(1);
                    }

Somewhere along the way it gets lost, and it always prints "Student not found", even when I know those particular results are in the file.

Sample File

Test
1
Female
93.0%
 
Test
2
Female
97.0%
 
Test
3
Female
100.0%

Solution

  • You don't need multiple scanners to get the user input. You can reuse one. The same applies for searching in the file, you only need one scanner. Apart from that, your file seems to be well formed, so you can use the Scanner.findAll method and pass a pattern that you can construct from the user's input. Something like below should get you started. Note: the example has no error handling, and also no case insensitive search. You can improve this yourself

    import java.io.File;
    import java.io.FileNotFoundException;
    import java.util.Scanner;
    import java.util.regex.MatchResult;
    import java.util.regex.Pattern;
    
    public class Example {
    
        public static void main(String[] args) throws FileNotFoundException {
    
            Scanner userInput = new Scanner(System.in);
    
            System.out.println("Please enter Student's full name below.");
            var stuName = userInput.nextLine();
    
            System.out.println("Please enter Student's age below.");
            var stuAge = userInput.nextInt();
            userInput.nextLine();   //this is not an oversight but intentional and necessary to be able to read the next input.
    
            System.out.println("Please enter Student's gender below (Female or Male).");
            var stuGender = userInput.nextLine();
    
            Scanner fileContent = new Scanner(new File("Example.txt"));
            //construct pattern from user input and regex for percentage
            Pattern pattern = Pattern.compile(stuName + "\n" + stuAge + "\n" + stuGender + "\n" + "\\d+(?:\\.\\d+)?%");
            //use findAll method and return first match if present
            fileContent.findAll(pattern)
                       .map(MatchResult::group)
                       .findFirst()
                       .ifPresentOrElse(
                               (value) -> System.out.println("Found matching result: \n" + value),
                               ()      -> System.out.println("No matching result found"));
    
        }
    }
    

    Edit:

    What is "\n\\d+(?:\\.\\d+)?%" and how does it relate to the pattern?

    I have separeted the new line char from the regex, to reduce confusion and chnged it to :

    `"\n" + "\\d+(?:\\.\\d+)?%"` 
    

    The \\d+(?:\\.\\d+)?% part is a regex that matches percentage for marks.

    • \\d+ match one or more digits
    • (?:\\.\\d+)? optionaly followed by a dot and one or more digits after the dot
    • % match the percent character

    So, possible matches could look like, where x is is any digit

    • x% ex. 7%
    • xx% ex. 27%
    • xx.x% ex. 97.4%
    • xx.xx% ex. 84.32%

    ``