Ошибка при использовании StringTokenizer для текстового файла с несколькими строками

#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));
        }
    }
}