2

Javaの文字列トークナイザーユーティリティを使用して、テキストファイルを読み取り、単語を個別に分割しようとしています。

テキストファイルは次のようになります。

a 2000

4  
b 3000  
c 4000  
d 5000

今、私がやろうとしているのは、テキストファイルから個々の文字を取得し、それを配列リストに格納することです。次に、最後に配列リスト内のすべての要素を出力してみます。

これが私のコードです。

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ファイルの名前です。

ありがとうございました。

4

4 に答える 4

6

a)常にStringTokenizer.hasMoreTokens()最初に確認する必要があります。使用可能なトークンがなくなった場合のスローNoSuchElementExceptionは、文書化された動作です。

token = new StringTokenizer (line);
while(token.hasMoreTokens())
    words.add(token.nextToken());

b)ファイルが大きすぎてメモリに収まらない場合を除いて、すべての行に新しいTokenizerを作成しないでください。ファイル全体を文字列に読み取り、トークナイザーがその上で動作するようにします

于 2011-05-02T10:45:50.733 に答える
2

一般的なアプローチは正しいように見えますが、コードに基本的な問題があります。

パーサーは、入力ファイルの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

于 2011-05-02T10:53:08.297 に答える
0

この問題は、次のトークンを取得しようとする前に、次のトークンがあるかどうかをテストしないという事実が原因です。を呼び出す前に、 hasMoreTokens()beforeが戻るかどうかを常にテストする必要があります。truenextToken()

しかし、他にもバグがあります:

  • 最初の行は読み取られますが、トークン化されません
  • 各行の最初の単語のみを単語リストに追加します
  • 悪い習慣:トークン変数はループの外側ではなく、ループの内側で宣言する必要があります
  • リーダーをfinallyブロックで閉じない
于 2011-05-02T10:49:36.853 に答える
0

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));
        }
    }
}
于 2011-05-02T11:15:00.147 に答える