简体   繁体   中英

Why are my variables being reset every time I continue a while loop?

I'm looping through a text file using both a while and for loop.

The goal of my code is to iterate through my CSV comma-delimited text file with 2 columns and only parse through strings to a map. I don't want integers, and that's what my program is meant to do.

The problem is, every time I restart the while loop to go to the next line, it restarts my variables and assumes it's always on the first line.

Here's my code:

        CSVReader reader = new CSVReader(new FileReader("sortMark12.txt"), ',');
        List<String[]> myEntries = reader.readAll();
        reader.close();

//mark12Line is a string of the file name, and mark12Br is a buffered reader

//While the text file's line is not empty
whileloop: while ((mark12Line = mark12Br.readLine()) != null)
        {
            //Declaring row, this keeps getting reset
            for (int row = 0; row < myEntries.size(); row++)
            {
                //Declaring column, this also keeps getting reset
                for (int column = 0; row < myEntries.get(row).length; column++)
                {
                    //While the row and column is not an integer
                    while (!isInteger(myEntries.get(row)[column]))
                    {
                        //Put the value in position row and column into the map.
                        mark12Map.put(mark12Line.split(",")[0], myEntries.get(row)[column]);
                        continue whileloop;
                    }
                }
            }
        }

What's happening in my code is that on the first row and first column, it detects it as an integer, so it does not put that integer into the map. The first row and second column is a string, so that is put inside the map.

The problem is, once that is done, it continues my while loop, and both row and column have been reset to 0. So it acts as if it's still on the same line, even though I have delcared it to increment at row++ and column++ .

Why do my integer variables keep getting reset to 0? I need them to increment everytime for a different line.

Am I declaring them wrong, or is something else breaking my code.

If you need any more code, then please let me know.

Thank you for your help.

From what I understand from your problem description and your response to Paul Guiheen's answer, I think the following code may be closer to your application's intended logic:

/* EDITED ...see below */

Problem

The row and column variables are being reset every time the outer while loop executes because they are being initialized inside the while loop. In other words, they will be re-initialized to zero every time the outer while loop executes.

You could move their initialize outside the outer while loop to avoid this, like so:

int row = 0;
int column = 0;
whileloop: while (/* test something */)
{
    for ( ; row < myEntries.size(); ++row)
    {
        for ( ; row < myEntries.get(row)[column]; ++column)
        {
            /* do stuff */;
        }
    }
}

This will fix the problem you asked about, and in some cases it may be justified. But in your case, it happens to create a second problem (see next paragraph). So I would say that there is a better way (see "Solution" section below).

The reason this won't work in your case is because you are using a continue <label> statement. The problem is that it will entirely skip and thus prevent the update statement of each for loop from executing. Unless you have a very good reason to use a continue <label> or break <label> statement, then don't . Jumping around your code like this can cause all sorts of hard-to-diagnose problems. And it's usually a sign of a fundamental design error anyway.

If you think you have to use a continue <label> or break <label> statement, then you probably need to refactor (ie re-structure your code so that you don't need to use it in the first place).


Solution

Basically, what you want to do is some variation of the following in order to iterate through every row, and within every row to iterate through every column:

for (int row = 0; row < myEntries.size(); ++row)
{
    for (int column = 0; column < myEntries.get(row).length; ++column)
    {
        /* do stuff */;
    }
}

Where your "stuff" is this:

if (!isInteger(myEntries.get(row)[column]))
{
    mark12Map.put(mark12Line.split(",")[0], myEntries.get(row)[column]);
}

But the confusing part is that you also have to read and validate a line every row:

if ((mark12Line = mark12Br.readline()) != null)
{
    /* process each column in the row */;
}

So where do you put it? Just inside the "row" for loop (so that you read one line for each row) and just outside the "column" for loop (because there are multiple columns in every one line):

for (int row = 0; row < myEntries.size(); ++row)
{
    if ((mark12Line = mark12Br.readline()) != null)
    {
        for (int column = 0; column < myEntries.get(row).length; ++column)
        {
            /* do stuff */;
        }
    }
}

This will get the job done, but it will take longer than needed. We can optimize this if we notice that whenever there are no more lines to read, then we are done even if we have not reached the maximum number of rows yet. So we add the following else block to the if that reads in a line:

else
{
    break;  // break out of outer loop because there are no more lines to read
}

Final Solution

Putting together all of the above, the final product looks like this:

for (int row = 0; row < myEntries.size(); ++row)
{
    if ((mark12Line = mark12Br.readline()) != null)
    {
        for (int column = 0; column < myEntries.get(row).length; ++column)
        {
            if (!isInteger(myEntries.get(row)[column]))
            {
                mark12Map.put(mark12Line.split(",")[0], myEntries.get(row)[column]);
            }
        }
    }
    else
    {
        break;
    }
}

I'm not sure if you are approaching the problem in the most appropriate manner but to answer the question you are declaring you variables incorrectly

//While the text file's line is not empty
int row = 0;
int column = 0
whileloop: while ((mark12Line = mark12Br.readLine()) != null)
        {
            //Declaring row, this keeps getting reset
            for (; row < myEntries.size(); row++)
            {
                //Declaring column, this also keeps getting reset
                for (; column < myEntries.get(row).length; column++)
                {
                    //While the row and column is not an integer
                    /*while*/ if (!isInteger(myEntries.get(row)[column]))
                    {
                        //Put the value in position row and column into the map.
                        mark12Map.put(mark12Line.split(",")[0], myEntries.get(row)[column]);
                        //continue whileloop;
                    }
                }
            }
        }

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