Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scanner & .hasNext() issue

I am new to Java and very new to the Scanner class. I am writing a program which asks the user for a word and then this word is searched for within a file. Each time the word is found, it is printed on a new line in a JOptionPane, as well as the word before and after it. Everything is functioning as it should, with two exceptions:

  1. If the word being searched for happens to be the last word in the file then a "NoSuchElementException" is thrown.

  2. If the word being searched for appears twice in a row (unlikely, but still a problem I discovered), it only returns it once. For example, if the word being searched for was "had" and "He said that he had had enough. He had been up all night" were sentences in the file, then the output is:

    he had had
    He had been
    

    whereas it should be:

    he had had
    had had enough.
    He had been
    

I believe that my problem lies in the fact that I use a while(scan.hasNext()) and within this loop I use scan.next() twice. I cannot find a solution for this though, while still achieving what I would like the program to return.

Here is my code:

//WordSearch.java
/*
 * Program which asks the user to enter a filename followed
 * by a word to search for within the file. The program then
 * returns every occurrence of this word as well as the
 * previous and next word it appear with. Each of these
 * occurrences are printed on a new line when displayed
 * to the user.
 */

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JOptionPane;

public class WordSearch {

    public static void main(String[] args) throws FileNotFoundException {

        String fileName = JOptionPane.showInputDialog("Enter the name of the file to be searched:");
        FileReader reader = new FileReader(fileName);

        String searchWord = JOptionPane.showInputDialog("Enter the word to be searched for in \"" + fileName + "\":");
        Scanner scan = new Scanner(reader);

        int occurrenceNum = 0;
        ArrayList<String> occurrenceList = new ArrayList<String>();
        String word = "", previousWord, nextWord = "", message = "", occurrence, allOccurrences = "";

        while(scan.hasNext()){
            previousWord = word;
            word = scan.next();

            if(word.equalsIgnoreCase(searchWord)){
                nextWord = scan.next();

                if(previousWord.equals("")){
                    message = word + " is the first word of the file.\nHere are the occurrences of it:\n\n";
                    occurrence = word + " " + nextWord;
                }
                else{
                    occurrence = previousWord + " " + word + " " + nextWord;
                }

                occurrenceNum++;
                occurrenceList.add(occurrence);
            }
        }

        for(int i = 0; i < occurrenceNum; i++){
            allOccurrences += occurrenceList.get(i) + "\n";
        }

        JOptionPane.showMessageDialog(null, message + allOccurrences);

        scan.close();
    }
}

Also, on a side note: How can I implement scan.useDelimeter() to ignore any, question marks, commas, periods, apostrophes etc?

like image 632
KOB Avatar asked Jul 26 '26 18:07

KOB


1 Answers

If the word being searched for happens to be the last word in the file then a NoSuchElementException is thrown.

This is because of this line:

if(word.equalsIgnoreCase(searchWord)) {
    nextWord = scan.next();
    ...
}

You do not check if the scan actually hasNext(), going straight for scan.next(). You can fix this by adding a conditional with a call to scan.hasNext()

If the word being searched for appears twice in a row (unlikely, but still a problem I discovered), it only returns it once.

That the same problem is in play here: when you find a word, you retrieve the next one right away.

Fixing this is a little tricky: you need to change your algorithm to look at one word at a time, and use previousWord (which you store anyway) for use of subsequent iterations of the while loop.

like image 65
Sergey Kalinichenko Avatar answered Jul 29 '26 07:07

Sergey Kalinichenko