Home > Net >  Java word counter doesn't count all the words
Java word counter doesn't count all the words

Time:10-29

This is the program I need to make,

Make a class that represents a file. This class will have the ability to calculate the number of lines in that file and the ability to search through the file. The getNumLinesThatContain method will take a bit of text and determine how many lines contain that text. Make the comparison not care about case. Example: if the user is searching for hello and a line contains the text hello hello hello then this counts as one. Use the contains method defined on Strings to help with this. Class Name FileStats Fields

  • filename : String Methods
  • FileStats(filename : String)
  • getNumLinesThatContain(key : String) : int
  • getNumLines() : int

This is what I have so far,

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Objects;
import java.util.Scanner;

public class FileStats {
    private String filename;
    Scanner inputFile;


    public FileStats(String f) {
        filename = f;
    }

    public int getNumLines() throws FileNotFoundException {
        //make a variable to hold the filename
        File fileObj = new File(filename);
        inputFile = new Scanner(fileObj);
        //keep track of the number lines
        int numLines = 0;
        //while there's more stuff to read...
        while (inputFile.hasNext()) {
            //read a line
            String line = inputFile.nextLine();
            //keep track of that line
            numLines  ;
        }
        //close the file
        inputFile.close();
        //return the result
        return numLines;
    }
    public int getNumLinesThatContain(String key){
        // variable to keep track of file name
        File fileObj = new File(filename);
        inputFile = new Scanner(filename);
        //keep track of the number lines
        int numLines = 0;

        //while there is more stuff to read
        while (inputFile.hasNext()){
            //read a line
            String line = inputFile.nextLine();
            //keep track of the line if word
            //this is where I think the problem is
            if(line.toUpperCase().contains(key.toUpperCase())) {
                numLines  ;
            }
        }
        inputFile.close();
        return numLines;
    }

}

For the method getNumLinesThatContain I just get 1s and 0s when I run the file. I have tried changing the if statement to one that compares line and key, to one that sees if they are equal, and the one shown checks to see if the line contains the key. I can't seem to figure out how to get the counter to count the lines that contain the key correctly. Please help.

CodePudding user response:

Isn't this your problem?

inputFile = new Scanner(filename);

It should be

inputFile = new Scanner(fileObj);

You should read from the file object and not from the String filename. You have used it correctly for the first method where you count all the lines.

CodePudding user response:

BE SIMPLE!!!

public final class FileStats {

    private final Path file;

    public FileStats(String pathname) {
        file = Paths.get(pathname);
    }

    public int getNumLines() throws IOException {
        return Files.readAllLines(file).size();
    }

    public int getNumLinesThatContain(String key) throws IOException {
        String lowerCaseKey = key.toLowerCase();

        return (int)Files.readAllLines(file).stream()
                         .map(String::toLowerCase)
                         .filter(line -> line.contains(lowerCaseKey))
                         .count();
    }

}

CodePudding user response:

If you do it like this, you can write ONE method that does BOTH: If the argument is null, all lines are counted. If the argument is a String (Case doesn't matter.), only lines are counted that contain that String.

final String keyLowerCase = key == null ? null : key.toLowerCase();
int amountOfLines = 0;
try (final BufferedReader br = Files.newBufferedReader(file.toPath(), StandardCharsets.UTF_8)) {
    String line;
    while ((line = br.readLine()) != null) {
        if (keyLowerCase == null || line.toLowerCase().contains(keyLowerCase)) {
            amountOfLines  ;
        }
    }
} catch (IOException e) {
    e.printStackTrace();
}

CodePudding user response:

This uses a BufferedReader to read in the lines as a stream. The mark and reset methods are used to essentially rewind the file for each method call.

public class FileStatsTest {
    public static void main(String[] args) {
        String searchString = "to";
        String fileName = "some file";
        FileStats fs = new FileStats(fileName);
        System.out.println(fs.getNumLines());
        System.out.println(fs.getNumLinesThatContain(searchString));
    }
}

class FileStats {
    private File file;
    BufferedReader br;

    public FileStats(String fileName) {
        file = new File(fileName);
        try {
            br = new BufferedReader(new FileReader(file));
            br.mark((int) file.length()   1); // just file.length() won't work
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
    }

    public int getNumLines() {
        try {
            br.reset(); // effectively reset to start of file
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }

        return (int) br.lines().count();
    }

    public int getNumLinesThatContain(String key) {
        String keyLC = key.toLowerCase();
        try {
            br.reset(); // effectively reset to start of file
        } catch (IOException ioe) {
            ioe.printStackTrace();
        }
        return (int) br.lines().filter(str -> str.toLowerCase().contains(key))
                .count();
    }
}

Limitations

  • This won't work for files larger than Integer.MAX_VALUE-1 as mark only accepts an integer value.
  • the returned count is a long and cast to an int. Not a problem since mark would fail long before the high order word of count is masked off from the cast.
  •  Tags:  
  • java
  • Related