Почему один оператор println изменяет весь вывод моего кода?

#java #file #file-io #java.util.scanner

#java #файл #file-io #java.util.scanner

Вопрос:

Проблема

В настоящее время я создаю программу для чтения файла и поиска пары переменных. Я сталкиваюсь с этой проблемой, когда изменение одного println изменяет весь вывод моего кода. Я никогда не сталкивался с этим раньше и не уверен, является ли это ошибкой eclipse или моей ошибкой?

Мой код

 import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class FileAnalyzer {
    public static void main(String args[]) throws IOException {
        Scanner input = new Scanner(System.in);
        String fileName;
        int words = 0, letters = 0, blanks = 0, digits = 0, miscChars = 0, lines = 0;

        System.out.print("Please enter the file path of a .txt file: ");
        fileName = input.nextLine();

        File text = new File(fileName);
        //System.out.println(text.exists());

        Scanner word = new Scanner(text);
        while(word.hasNext()) {
            //System.out.println(word.next());
            words  ;
        }
        word.close();

        Scanner letter = new Scanner(text);
        while(letter.hasNext()) {
            String currentWord = letter.next().toLowerCase();
            for(int i = 0; i < currentWord.length(); i  ) {
                if(Character.isLetter(currentWord.charAt(i))) {
                    letters  ;
                }
            }
        }
        letter.close();

        Scanner blank = new Scanner(text);
        while(blank.hasNextLine()) {
            String currentWord = blank.nextLine();
            for(int j = 0; j < currentWord.length(); j  ) {
                if (currentWord.charAt(j) == ' ') {
                    blanks  ;
                }
            }
        }
        blank.close();

        System.out.println("Words: "   words);
        System.out.println("Letters: "   letters);
        System.out.println("Blanks: "   blanks);


    }
}
  

Однако

Простое изменение System.out.println(word.next()) в первом экземпляре сканера изменяет весь вывод. Если я оставлю это, я получу три оператора печати внизу и то, что я ищу. Если я удалю его, поскольку я не хочу, чтобы каждое слово печаталось в файле, оно не отображается как ничто в консоли. Не уверен, почему один оператор печати в операторе while изменяет весь вывод.Единственная причина, по которой он был там в первую очередь, заключалась в том, чтобы убедиться, что сканер принимает входные данные так, как я хотел.

Ответ №1:

Не уверен, почему один оператор печати в операторе while изменяет весь вывод

Потому что, когда оператор присутствует, вы потребляете токен из сканера. Когда он закомментирован, вы этого не делаете. Токен потребляет не печать, а вызов next() .

После того, как он закомментирован, ваш цикл:

 while (word.hasNext()) {
    words  ;
}
  

hasNext() не изменяет состояние сканера, так что он будет просто зацикливаться вечно, если вообще попадет в тело цикла.

Если вы хотите иметь строку, которую вы можете закомментировать или нет, измените код на:

 while (word.hasNext()) {
    String next = word.next(); // Consume the word
    System.out.println(next); // Comment this out if you want to
    words  ;
}
  

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

1. @IanHank: Да, это было бы к лучшему, хотя на самом деле это ортогонально вопросу.

Ответ №2:

С помощью System.out.println(word.next()); вы перебираете элементы в коллекции из-за next() метода. Таким образом, вызов next() напрямую позволит вам перемещаться по итерации.

При комментировании //System.out.println(word.next()); это word.hasNext() приведет к бесконечному циклу (при условии, что есть слово), поскольку вы не сможете перейти к следующему токену.

Приведенный ниже фрагмент поможет вам достичь желаемого результата

 while(word.hasNext()){
   word.next();
   words  ;
}
  

Ответ №3:

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

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

1. Хотя в целом это хорошая идея, я не думаю, что это отвечает на вопрос о том, почему код ведет себя по-другому с закомментированным оператором.

2. Обычно я бы этого не сделал, но учитель хочет, чтобы мы это сделали, чтобы мы попрактиковались, я думаю? На самом деле я закрыл все три сразу после публикации и подумал, что кто-нибудь прокомментирует это.