Java 对包含多行的文本文件使用StringTokenizer时出错

Java 对包含多行的文本文件使用StringTokenizer时出错,java,file-io,stringtokenizer,Java,File Io,Stringtokenizer,我正在尝试读取一个文本文件,并使用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.

我正在尝试读取一个文本文件,并使用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));
    }



}
导入java.io.BufferedReader;
导入java.io.FileReader;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.StringTokenizer;
公共静态void main(字符串[]args){
字符串fileSpecified=args[0];
fileSpecified=fileSpecified.concat(“.txt”);
弦线;
System.out.println(“指定的文件=”+指定的文件);
ArrayList words=新的ArrayList();
试一试{
FileReader fr=新的FileReader(指定文件);
BufferedReader br=新的BufferedReader(fr);
line=br.readLine();
StringTokenizer令牌;
而((line=br.readLine())!=null){
令牌=新的StringTokenizer(行);
words.add(token.nextToken());
}
}捕获(IOE异常){
System.out.println(e.getMessage());
}
for(int i=0;i
我得到的错误信息是:

Exception in thread "main" java.util.NoSuchElementException   
                at java.util.StringTokenizer.nextToken<Unknown Source>  
                at getWords.main<getWords.java:32>  
线程“main”java.util.NoSuchElementException中的异常 位于java.util.StringTokenizer.nextToken 在getWords.main
其中'getWords'是我的java文件的名称

谢谢。

a)你总是要先检查一下。如果没有更多的令牌可用,则抛出
NoSuchElementException
是记录在案的行为:

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

b) 不要为每一行创建新的标记器,除非您的文件太大,无法放入内存。将整个文件读取为一个字符串,并让标记器处理该字符串。此问题是因为在尝试获取下一个标记之前,您没有测试是否存在下一个标记。在调用
nextToken()
之前,您应该始终测试
hasMoreTokens()
是否返回
true

但您还有其他错误:

  • 第一行已读取,但未标记
  • 您只需将每行的第一个单词添加到单词列表中
  • 错误做法:令牌变量应该在循环内声明,而不是在循环外声明
  • 你不会在最后一个区块关闭你的阅读器

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

您的解析器很可能在输入文件的第二行失败。这一行是空行,所以当您调用
words.add(token.nextToken())时您将收到一个错误,因为没有令牌。这也意味着您只能在每行上获得第一个令牌

您应该像这样迭代托克斯:

while(token.hasMoreTokens())
{
    words.add(token.nextToken())
}
您可以在这里的javadocs中找到一个更一般的示例:


您需要使用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));
        }
    }
}
导入java.io.BufferedReader;
导入java.io.FileReader;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.StringTokenizer;
公共类TestStringTokenizer{
/**
*@param args
*@抛出异常
*/
公共静态void main(字符串[]args)引发IOException{
字符串fileSpecified=args[0];
fileSpecified=fileSpecified.concat(“.txt”);
弦线;
System.out.println(“指定的文件=”+指定的文件);
ArrayList words=新的ArrayList();
BufferedReader br=新的BufferedReader(新文件读取器(文件指定));
试一试{
而((line=br.readLine())!=null){
StringTokenizer令牌=新的StringTokenizer(行);
while(token.hasMoreTokens())
words.add(token.nextToken());
}
}捕获(IOE异常){
System.out.println(e.getMessage());
e、 printStackTrace();
}最后{
br.close();
}
for(int i=0;i