2

我正在尝试读取文本文件并使用 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 文件的名称。

谢谢你。

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

您的一般方法似乎很合理,但是您的代码中有一个基本问题。

您的解析器很可能在输入文件的第二行失败。这一行是一个空行,所以当你调用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

这个问题是由于您在尝试获取下一个令牌之前没有测试是否有下一个令牌。您应该始终在调用之前测试 if 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 回答