扫描仪& .hasNext()问题

时间:2015-10-30 18:16:39

标签: java java.util.scanner

我是Java的新手,也是Scanner类的新手。我正在编写一个程序,要求用户输入一个单词,然后在一个文件中搜索这个单词。每次找到该单词时,它都会打印在JOptionPane中的新行以及它之前和之后的单词上。一切都按预期运作,但有两个例外:

  1. 如果搜索的单词恰好是文件中的最后一个单词,则会抛出“NoSuchElementException”。

  2. 如果被搜索的单词连续出现两次(不太可能,但我发现仍有问题),它只返回一次。例如,如果被搜索的单词是“had”和“他说他已经受够了。他已经整晚都在上面”是文件中的句子,那么输出是:

    he had had
    He had been
    

    应该是:

    he had had
    had had enough.
    He had been
    
  3. 我相信我的问题在于我使用了while(scan.hasNext())并且在此循环中我使用了scan.next()两次。我找不到解决方案,虽然仍然实现了我想要的程序返回。

    这是我的代码:

    //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();
        }
    }
    

    此外,在旁注:我如何实施scan.useDelimeter()来忽略任何问号,逗号,句号,句点,撇号等?

3 个答案:

答案 0 :(得分:4)

  

如果搜索的单词恰好是文件中的最后一个单词,则会抛出NoSuchElementException

这是因为这一行:

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

您不会直接检查scan hasNext()是否scan.next()。您可以通过调用scan.hasNext()

添加条件来解决此问题
  

如果被搜索的单词连续出现两次(不太可能,但我发现仍有问题),它只会返回一次。

同样的问题在这里发挥作用:当你找到一个单词时,你立即检索下一个单词。

修复此问题有点棘手:您需要更改算法以一次查看一个单词,并使用previousWord(无论如何存储)以使用while的后续迭代循环。

答案 1 :(得分:1)

你可以做的就是在再次使用next之前调用hasNext。

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

    if(word.equalsIgnoreCase(searchWord) && scan.hasNext()){ // this line change
        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);
    }
}

您希望不使用带有忽略大小写的等号。你想只使用.equals()。

答案 2 :(得分:1)

解决方案是以您当前保存previousWord的方式保存两个字词。类似的东西:

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

然后你检查word。如果它符合您的需要,则可以与previousWordnextWord一起打印。也就是说,在每次迭代中,您都在检查您在上一次迭代中读取的单词。

这样,您的循环中只需要一个hasNext()和一个next()

请注意,在循环结束后,nextWord可能实际上是您的单词。这意味着你的单词是文件中的最后一个单词,你应该检查并相应地打印它。