#java #file-io #stringtokenizer
#java #file-io #stringtokenizer
Вопрос:
Я пытаюсь прочитать текстовый файл и разделить слова по отдельности с помощью утилиты string tokenizer на Java.
Текстовый файл выглядит следующим образом;
a 2000
4
b 3000
c 4000
d 5000
Теперь, что я пытаюсь сделать, это получить каждый отдельный символ из текстового файла и сохранить его в списке массива. Затем я пытаюсь напечатать каждый элемент в arraylist в конце.
Вот мой код;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
public static void main(String[] args) {
String fileSpecified = args[0];
fileSpecified = fileSpecified.concat(".txt");
String line;
System.out.println ("file Specified = " fileSpecified);
ArrayList <String> words = new ArrayList<String> ();
try {
FileReader fr = new FileReader (fileSpecified);
BufferedReader br = new BufferedReader (fr);
line = br.readLine();
StringTokenizer token;
while ((line = br.readLine()) != null) {
token = new StringTokenizer (line);
words.add(token.nextToken());
}
} catch (IOException e) {
System.out.println (e.getMessage());
}
for (int i = 0; i < words.size(); i ) {
System.out.println ("words = " words.get(i));
}
}
Сообщение об ошибке, которое я получаю, это;
Exception in thread "main" java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken<Unknown Source>
at getWords.main<getWords.java:32>
Где ‘getWords’ — это имя моего java-файла.
Спасибо.
Ответ №1:
a) Вы всегда должны сначала проверить StringTokenizer.hasMoreTokens()
. Выбрасывание NoSuchElementException
— это документированное поведение, если больше нет доступных токенов:
token = new StringTokenizer (line);
while(token.hasMoreTokens())
words.add(token.nextToken());
б) не создавайте новый токенизатор для каждой строки, если только ваш файл не слишком велик, чтобы поместиться в памяти. Прочитайте весь файл в строку и дайте токенизатору поработать над этим
Ответ №2:
Ваш общий подход кажется разумным, но у вас есть основная проблема в вашем коде.
Ваш анализатор, скорее всего, выдает ошибку во второй строке вашего входного файла. Эта строка является пустой строкой, поэтому при вызове words.add(token.nextToken());
вы получаете сообщение об ошибке, потому что нет токенов. Это также означает, что вы будете получать только первый токен в каждой строке.
Вы должны выполнить итерацию по нажатиям следующим образом:
while(token.hasMoreTokens())
{
words.add(token.nextToken())
}
Вы можете найти более общий пример в javadocs здесь:
http://download.oracle.com/javase/1.4.2/docs/api/java/util/StringTokenizer.html
Ответ №3:
Эта проблема связана с тем, что вы не проверяете, есть ли следующий токен, прежде чем пытаться получить следующий токен. Вы всегда должны проверять, возвращает ли hasMoreTokens()
before true
перед вызовом nextToken()
.
Но у вас есть другие ошибки :
- Первая строка прочитана, но не помечена
- Вы добавляете только первое слово каждой строки в свой список слов
- плохая практика: переменная token должна быть объявлена внутри цикла, а не снаружи
- вы не закрываете свой reader в блоке finally
Ответ №4:
Вам нужно использовать метод hasMoreTokens(). Также устранены различные проблемы со стандартом кодирования в вашем коде, как указано JB Nizet
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;
public class TestStringTokenizer {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
String fileSpecified = args[0];
fileSpecified = fileSpecified.concat(".txt");
String line;
System.out.println ("file Specified = " fileSpecified);
ArrayList <String> words = new ArrayList<String> ();
BufferedReader br = new BufferedReader (new FileReader (fileSpecified));
try{
while ((line = br.readLine()) != null) {
StringTokenizer token = new StringTokenizer (line);
while(token.hasMoreTokens())
words.add(token.nextToken());
}
} catch (IOException e) {
System.out.println (e.getMessage());
e.printStackTrace();
} finally {
br.close();
}
for (int i = 0; i < words.size(); i ) {
System.out.println ("words = " words.get(i));
}
}
}