tags:

views:

327

answers:

7

I am new to Java. I tried to extract employee data from a text file and store it in a collection. I used Stringtokenizer to get the strings from the file, but in the second iteration, the while loop goes infinite; it won't come out of the while loop. My code is:

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

Please suggest a solution.

+9  A: 

Hmm, so what happens when count goes to 3? You don't call nextToken any more so you'll never run out of tokens.

You really don't need that inner loop. You always want to pull 2 tokens out of that string, so just do that! You may want some error handling in case a line doesn't have 2 tokens, though.

Carl Smotricz
in the text file i ve only two strings for each line liketom 5647james 4628so the st has only two tokens after that while loop should come out right
Karthik.m
If it were working correctly you wouldn't be asking for help. Just do `e.ename = st.nextToken(); e.eno = st.nextToken(); al.add(e);` instead of that whole inner `while` loop.
Carl Smotricz
That, or set `count = 0;` just before the inner `while`.
Carl Smotricz
thanks carl now it works
Karthik.m
A: 

Consider what happens when count==3 or more. You stop calling st.nextToken() as soon as count goes above 2. Since you're not advancing the token by calling nextToken(), st.hasMoreTokens() will keep returning true forever and your loop will never exit.

Gene Goykhman
A: 

Your loop will apparently hang up for any line with more than 2 tokens.

You should break from loop in this case. E.g.

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);
    }
}
elder_george
A: 

Running that through my head, the only thing that looks like it might cause an infinite loop somewhere in that loop is if there are more than 2 records in that string. When the count is less than 0 or greater than 1 at the start of a loop iteration, no tokens are consumed (via nextToken()).

It might be a better idea to consume all of the tokens into an array and then keep just the ones you care about.

s1n
+1  A: 

The problem is you're not resetting count. So, after the first time through the loop, count == 2 and on the second time through, count gets incremented to 3. Since you don't handle a case of count == 3 the loop continues forever.

Wade Williams
+2  A: 

As Carl mentions, you aren't calling nextToken after the count is greater than 3. What you seem to be missing is a count = 0; right after the close parentheses for if (count == 2).

Edit (To make the answer more useful)

The count = 0; was a simple fix for your issue. It fixed the fact that you stopped calling st.nextToken() if count was greater than 2.

Considering your mentioning that it your data is a line with two strings with a distinct delimiter between them, I would likely just use

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

It will show bad data better than the string tokenizer. A missing end line, could cause you to miss or overwrite an employee.

If you really want to use a string tokenizer, I think you may have been going for something like this

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

Your current while loop can be simplified to (It looks like you may also be adding an incomplete Employee object. with your current while loop)

e.name = st.nextToken();
e.n0 = st.nextToken();
al.add(e);
Philip T.
+2  A: 

just try this code

while(st.hasMoreTokens())
   {

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

}

I think this will solve your problem....

Hari