2009-11-20 113 views
3

我是Java新手。我试图从文本文件中提取员工数据并将其存储在集合中。我使用Stringtokenizer从文件中获取字符串,但在第二次迭代中,while循环变为无限;它不会从while循环中出来。我的代码是:无限循环在java中

public class Reader1 { 
    String a; 
    int i = 0; 
    int count = 0; 
    int x = 0; 
    int y = 0; 
    File f = new File(
      "C:\\Documents and Settings\\kmoorthi\\Desktop\\ak\\sample.txt"); 

    ArrayList<Employee> al = new ArrayList<Employee>(); 

    public void notePad() throws IOException { 

     try { 
      FileReader fis = new FileReader(f); 
      BufferedReader br = new BufferedReader(fis); 

      do { 
       a = br.readLine(); 
       i++; 
       if (i > 1) { 
        if (a != null) { 
         StringTokenizer st = new StringTokenizer(a, " "); 
         Employee e = new Employee(); 
         System.out.println("hai1"); 
         while (st.hasMoreTokens()) // here became infinite 
         { 
          count++; 
          if (count == 1) { 
           e.ename = st.nextToken(); 
           al.add(e); 
          } 

          if (count == 2) { 
           e.eno = st.nextToken(); 
           al.add(e); 
          } 
         } 
        } 
       } 
      } while (a != null); 
      br.close(); 

     } catch (FileNotFoundException q) { 
      q.printStackTrace(); 
     } 
    } 

    public void retrieve() { 
     Iterator<Employee> it = al.iterator(); 
     while (it.hasNext()) { 
      Employee fi = (Employee) it.next(); 
      String en = fi.ename; 
      System.out.println(en); 
     } 
    } 

    public static void main(String s[]) throws IOException { 
     Reader1 r = new Reader1(); 
     r.notePad(); 
     r.retrieve(); 
    } 
} 

请建议解决方案。

回答

2

只是尽量在文本文件中的代码

while(st.hasMoreTokens()) 
{ 

    if(count==1) 
    { 
     e.ename=st.nextToken(); 
     count++; 
    } 
    if(count==2) 
    { 
     e.eno=st.nextToken(); 
     count=0; 
    } 
    a1.add(e); 
} 

我认为这将解决您的问题....

9

嗯,那么count到3时会发生什么?你不再打电话nextToken,所以你永远不会用完令牌。

你真的不需要那个内部循环。你总是想从这个字符串中拉出两个令牌,所以就这么做!但是,如果某行不具有2个标记,您可能需要进行一些错误处理。

+0

我已经只有两根弦的每一行像 汤姆5647 詹姆斯4628 所以ST只有两个令牌后,而循环应该出来正确 – 2009-11-20 06:45:45

+0

如果它工作正常,你不会寻求帮助。只要做'e.ename = st.nextToken(); e.eno = st.nextToken(); al.add(e);'而不是整个内部'while'循环。 – 2009-11-20 06:59:04

+0

或者在内部'while'之前设置'count = 0;'。 – 2009-11-20 07:01:25

0

考虑当count == 3或更多时会发生什么。只要count超过2,就停止调用st.nextToken()。由于您没有通过调用nextToken()来推进该标记,st.hasMoreTokens()将永远保持返回true,并且您的循环将永远不会退出。

0

您的循环显然会挂起超过2个标记的任何行。

在这种情况下,您应该从循环中断开。例如。

while(st.hasMoreTokens() && count < 2) 
{ 
    count++; 
    if(count==1) 
    { 
     e.ename=st.nextToken(); 
     al.add(e); 
    } 
    if(count==2) 
    { 
     e.eno=st.nextToken(); 
     al.add(e); 
    } 
} 
0

运行,通过我的头,看起来像它可能导致无限循环的地方在循环的唯一的事情是,如果有超过2个记录该字符串。当循环迭代开始时count小于0或大于1时,不会使用令牌(通过nextToken())。

将所有令牌消耗到数组中然后保留你所关心的令牌可能是一个更好的主意。

1

问题是你没有重置计数。因此,在第一次循环之后,count == 2并在第二次通过时,count会增加到3.因为您不处理count == 3的情况,所以循环会一直持续。

2

正如Carl所说,在count大于3之后,你并没有调用nextToken。你似乎缺少的是count = 0;在if(count == 2)的右括号之后。

编辑(使答案更有用)

计数= 0;对于你的问题是一个简单的修复。它修正了事实,即如果count大于2,则停止调用st.nextToken()。

考虑到您提到它的数据是两行之间带有明确分隔符的行,我可能会使用

e.name = line.subString(0, line.indexOf(" ")); 
e.no = line.subString(line.indexOf(" ") + 4); 

它会显示比字符串标记器更好的错误数据。缺少的最后一行,可能会导致您错过或覆盖员工。

如果你真的想用一个字符串标记,我想你可能已经持续这样的事情

count = 0; 
while (st.hasMoreTokens()) 
{ 
    if (count == 0) 
    { 
     e.name = st.nextToken(); 
    } 
    if (count == 1) 
    { 
     e.n0 = st.nextToken(); 
    } 
    st.nextToken(); 
    count++; 
} 
al.add(e); 

您当前while循环可以简化为(看起来你也可添加不完整的Employee对象。与您当前while循环)

e.name = st.nextToken(); 
e.n0 = st.nextToken(); 
al.add(e);