2009-11-20 4 views
3

Я новичок в Java. Я попытался извлечь данные сотрудника из текстового файла и сохранить его в коллекции. Я использовал Stringtokenizer для получения строк из файла, но во второй итерации цикл while бесконечен; он не выйдет из цикла 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 жетона из этой строки, так что просто сделайте это! Возможно, вам понадобится некоторая обработка ошибок, если в строке нет 2 токенов.

+0

в текстовом файле я ве только две строки для каждой строки например, Том 5647 james 4628 поэтому у st есть только два токена после этого, а петля должна выйти правильно –

+0

Если бы он работал правильно, вы не просили бы о помощи. Просто сделайте 'e.ename = st.nextToken(); e.eno = st.nextToken(); al.add (e); 'вместо этого целого внутреннего цикла while. –

+0

Это, или установите 'count = 0;' непосредственно перед внутренним 'while'. –

0

Рассмотрите, что происходит, когда счетчик = 3 или более. Вы перестаете называть st.nextToken(), как только счет идет выше 2. Поскольку вы не продвигаете токен, вызывая nextToken(), st.hasMoreTokens() будет продолжать возвращать true навсегда, и ваш цикл никогда не выйдет.

0

Ваша петля, видимо, повесит трубку для любой линии с более чем двумя жетонами.

В этом случае вы должны выйти из цикла. Например.

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 записи в этой строке. Когда счетчик меньше 0 или больше 1 в начале итерации цикла, токены не потребляются (через nextToken()).

Возможно, было бы лучше использовать все токены в массиве, а затем сохранить только те, о которых вы заботитесь.

1

Проблема в том, что вы не сбрасываете счет. Итак, после первого раза через цикл count == 2 и во второй раз счетчик увеличивается до 3. Поскольку вы не обрабатываете случай count == 3, цикл продолжается навсегда.

2

Как упоминает Карл, вы не вызываете nextToken после того, как счет больше 3. То, что вам кажется недостающим, - count = 0; сразу после закрытых круглых скобок для if (count == 2).

Edit (Для того, чтобы сделать ответ более полезным)

Количество = 0; было простым решением для вашей проблемы. Он зафиксировал тот факт, что вы перестали называть st.nextToken(), если счетчик был больше 2.

Учитывая ваше упоминание о том, что это ваши данные - это строка с двумя строками с четким разделителем между ними, я бы просто использовал

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

Он будет показывать плохие данные лучше, чем строковый токенизатор. Отсутствующая конечная строка может привести к пропуску или перезаписке сотрудника.

Если вы действительно хотите использовать строку Tokenizer, я думаю, что вы, возможно, происходит что-то вроде этого

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

Ваше текущее время цикла может быть упрощена (Похоже, вы можете также добавив неполный объект Employee.с током в то время как петля)

e.name = st.nextToken(); 
e.n0 = st.nextToken(); 
al.add(e); 
Смежные вопросы