简体   繁体   中英

Infinite while loop in java

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.

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.

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

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....

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.

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.

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

You should break from loop in this case. Eg

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM