Как сканировать файл на наличие определенной буквы в Java

#java

#java

Вопрос:

Мне нужно взять файл, который выбирает пользователь, и просканировать этот файл на наличие буквы, которую выбирает пользователь, а затем вывести, сколько раз письмо пользователя появлялось в файле.

Я знаю, как получить пользовательский ввод и заставить пользователя выбрать файл, а также сканировать файл, но я не могу найти способ проверить каждый символ в файле на наличие определенной буквы. Самое близкое, что я смог найти, это:

 public class FileLetterCounter
{
  public static void main(String[] args) throws IOException
  {
    int count = 0, stringLength;
    String file, a = "a";
    Scanner fileScanner, letterScan;
    ArrayList<String> line = new ArrayList<String>();

    fileScanner = new Scanner(new File("lab6.txt"));

    while (fileScanner.hasNext())
    {
      line.add(fileScanner.next());
  
      for (int index = 0; index < line.length(); index   )
      {
        if (line.get(index).contains(a));
        {
          count  ;
        }
      }
    } 
  }  
}
  

Это не работает, потому что метод length() не работает с ArrayList, и я не уверен, как подойти к проблеме. Я задаю этот вопрос, потому что нашел похожий, но рекомендуемым решением было использовать то, что у меня есть прямо сейчас в моем цикле for (строка.length()), но это не сработает.

Комментарии:

1. length() не работает с коллекциями, но size() , безусловно, работает. Также ваш for цикл должен быть вне вашего цикла while, потому что вы хотите накопить строки, а затем посчитать их. Альтернативным вариантом было бы вообще не иметь списка, а просто считать каждую строку, когда вы ее читаете. Я бы также использовал BufferedReader and readLine() вместо сканера. Чтобы выяснить, что происходит не так, я бы попробовал отладку printf. Или в Java System.out.println() debugging. tedspence.com/the-art-of-printf-debugging-7d5274d6af44

2. @Gray Я должен использовать сканер на основе моего назначения. Будет ли функция size() работать аналогично функции length()?

Ответ №1:

Вместо того, чтобы добавлять его в список, просто сканируйте текст в строку, повторяйте каждый символ строки, чтобы проверить, совпадает ли символ с символом поиска, и увеличивайте значение count для каждого совпадения.

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

public class Main {
    public static void main(String[] args) throws FileNotFoundException {
        int count = 0;
        Scanner keyboard = new Scanner(System.in);

        System.out.println("Enter the char to search: ");
        char searchChar = keyboard.next().charAt(0);

        Scanner fileScanner = new Scanner(new File("lab6.txt"));

        while (fileScanner.hasNext()) {
            String text = fileScanner.next();
            for (int index = 0; index < text.length(); index  ) {
                if (text.charAt(index) == searchChar) {
                    count  ;
                }
            }
        }

        System.out.println("The character "   searchChar   " appears "   count   " times in the file.");
        fileScanner.close();
    }
}
  

Комментарии:

1. fileScanner должен быть закрыт, чтобы освободить указатель на файл!

2. Я бы предпочел try with resources .

3. @oleg.cherednik — Спасибо за отзыв. Я бы также воспользовался try-with-resources, но, учитывая зрелость OP, я не представил его в своем ответе; скорее, я сосредоточился на том, как получить счетчик, который был основной проблемой, для которой OP попросил решение.

Ответ №2:

Посмотрите на эту реализацию с Streams помощью . Выглядит довольно мило для меня. Кроме того, не забудьте указать Charset , иначе вы можете получить неожиданные результаты.

 public static long countCharacterInFile(Path file, char ch, Charset charset) throws IOException {
    try (Stream<String> stream = Files.lines(file, charset)) {
        return stream.map(String::codePoints)
                     .flatMap(IntStream::boxed)
                     .filter(c -> c == ch)
                     .count();
    }
}
  

Вывод:

 Path file = Paths.get("lab6.txt");
System.out.println(countCharacterInFile(file, 'e', StandardCharsets.UTF_8));    // 666
  

Ответ №3:

Предполагая, что вы пытаетесь выполнить поиск символа во всем файле. Модифицировал код, удалив все эти ненужные переменные. Также я не вижу смысла добавлять каждую строку в список строк.

Идея состоит в том, чтобы сканировать каждую строку и увеличивать количество, если текущий символ соответствует вашему символу

 public class FileLetterCounter
{
  public static void main(String[] args) throws IOException
  {
    int count = 0;
    char targetLetter = 'a'; //define whatever you want or take it from user input
    Scanner fileScanner = new Scanner(new File("lab6.txt"));
    while (fileScanner.hasNext()) {
      String line = fileScanner.nextLine();
      for(int i=0; i<line.length(); i  ) {
        if(line.charAt(i) == targetLetter) {
          count  ;
        }
      }
    }
    System.out.println(count);
  }
}