Java 扫描仪&。hasNext()问题
我是Java新手,对Java 扫描仪&。hasNext()问题,java,java.util.scanner,Java,Java.util.scanner,我是Java新手,对Scanner类非常陌生。我正在编写一个程序,要求用户输入一个单词,然后在文件中搜索这个单词。每次找到该单词时,它都会打印在JOptionPane中的新行上,以及前后的单词。除了两个例外,一切正常运行: 如果正在搜索的单词恰好是文件中的最后一个单词,则会抛出“NoTouchElementException” 如果要搜索的单词连续出现两次(不太可能,但仍然是我发现的问题),它只返回一次。例如,如果正在搜索的单词是“had”和“他说他受够了。他整晚都没睡”是文件中的句子,那么输出
Scanner
类非常陌生。我正在编写一个程序,要求用户输入一个单词,然后在文件中搜索这个单词。每次找到该单词时,它都会打印在JOptionPane中的新行上,以及前后的单词。除了两个例外,一切正常运行:
he had had
He had been
鉴于它应该是:
he had had
had had enough.
He had been
,在这个循环中我使用了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();
}
}
//WordSearch.java
/*
*要求用户输入文件名的程序
*在文件中搜索一个单词。那么节目呢
*返回此单词的每次出现以及
*上一个单词和下一个单词一起出现。每一个
*显示时,引用将打印在新行上
*给用户。
*/
导入java.io.FileNotFoundException;
导入java.io.FileReader;
导入java.util.ArrayList;
导入java.util.Scanner;
导入javax.swing.JOptionPane;
公共类词汇搜索{
公共静态void main(字符串[]args)引发FileNotFoundException{
String fileName=JOptionPane.showInputDialog(“输入要搜索的文件名:”);
FileReader=新的FileReader(文件名);
String searchWord=JOptionPane.showInputDialog(“在\”“+fileName+“\”:”)中输入要搜索的单词;
扫描仪扫描=新扫描仪(读卡器);
int-occurrenceNum=0;
ArrayList occurrenceList=新建ArrayList();
字符串单词=”,上一个单词,下一个单词=”,消息=”,出现,异变=”;
while(scan.hasNext()){
先前的单词=单词;
word=scan.next();
if(word.equalsIgnoreCase(searchWord)){
nextWord=scan.next();
if(前面的单词等于(“”){
message=word+“是文件的第一个单词。\n出现的单词有:\n\n”;
出现次数=单词+“”+nextWord;
}
否则{
出现次数=上一个单词+“”+单词+“”+下一个单词;
}
发生数++;
事件列表。添加(事件);
}
}
for(int i=0;i
另外,还有一点需要注意:如何实现scan.useDelimeter()
忽略任何问号、逗号、句点、撇号等?在再次使用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。您只需要使用.equals()
如果正在搜索的单词恰好是文件中的最后一个单词,则会抛出NoSuchElementException
这是因为这一行:
if(word.equalsIgnoreCase(searchWord)) {
nextWord = scan.next();
...
}
您不检查扫描是否实际具有下一个()
,直接进入扫描.next()
。您可以通过调用scan.hasNext()
如果要搜索的单词连续出现两次(不太可能,但仍然是我发现的问题),它只返回一次
这里也存在同样的问题:当你找到一个单词时,你会立即检索下一个单词
解决这一问题有点棘手:您需要更改算法,一次查看一个单词,并使用上一个单词(您无论如何都要存储它),以用于while
循环的后续迭代。解决方案是以当前保存上一个单词的方式保存两个单词。比如:
while (scan.hasNext()) {
previousWord = word;
word = nextWord;
nextWord = scan.next();
然后你检查word
。如果它符合您的需要,那么您可以将它与previousWord
和nextWord
一起打印。也就是说,在每次迭代中,您都要检查在上一次迭代中读取的单词
这样,循环中只需要一个hasNext()
和一个next()
请注意,在循环结束后,nextWord
实际上可能是您的单词。这意味着您的单词是文件中的最后一个单词,您应该检查并相应地打印它。我是否可以建议您将其分解为多个功能?是的,我正计划这样做,然后将其全部清理干净。。。。。就在我们都读过之后。请注意,将代码分解为函数通常有助于您发现类似的问题。这样会不会有点翻转问题,并且如果是文件中的第一个单词,它将无法识别该单词?不会。因为尽管您只在第二轮而不是第一轮检查它,以前的单词
在当时仍然是”
,你会找到的。延迟处理导致的唯一问题是当单词是文件中的最后一个单词时——正如我已经提到的。您可能还需要注意一个案例,文件中只有一个单词。谢谢您的解决方案,一切都很好!我的最后一个问题是,如果搜索的单词出现了,但后跟句点/逗号/问号/等等,那么它就不会被识别为匹配项。我看过Scanner.useDelimter()方法,但我真的不了解它的格式以及如何将其转换为functi