为什么每次我继续 while 循环时我的变量都会被重置?
Why are my variables being reset every time I continue a while loop?
我正在使用 while 和 for 循环遍历文本文件。
我的代码的目标是遍历包含 2 列的 CSV 逗号分隔文本文件,并且仅将字符串解析为地图。我不想要整数,这就是我的程序要做的。
问题是,每次我重新启动 while 循环以转到下一行时,它都会重新启动我的变量并假定它始终在第一行。
这是我的代码:
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;
}
}
}
}
我的代码中发生的事情是,在第一行和第一列,它将它检测为一个整数,因此它不会将该整数放入地图中。第一行第二列是一个字符串,所以放在地图里面。
问题是,一旦完成,它会继续我的 while 循环,并且 row
和 column
都已重置为 0。所以它就像仍在同一行上一样,即使我已将其递增至 row++
和 column++
.
为什么我的整数变量总是重置为 0?我需要他们每次为不同的行递增。
我是说他们错了,还是其他什么破坏了我的代码。
如果您需要更多代码,请告诉我。
感谢您的帮助。
我不确定您是否以最恰当的方式解决了问题,但是回答您错误地声明变量的问题
//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;
}
}
}
}
根据我从您的问题描述和您对 Paul Guiheen 回答的回复中了解到的情况,我认为以下代码可能更接近您的应用程序的预期逻辑:
/* EDITED ...see below */
问题
每次执行外部 while
循环时都会重置 row
和 column
变量,因为它们正在 内部 while
循环。换句话说,每次执行外部 while
循环时,它们将被重新初始化为零。
您可以将它们的初始化 移到 外部 while
循环之外以避免这种情况,如下所示:
int row = 0;
int column = 0;
whileloop: while (/* test something */)
{
for ( ; row < myEntries.size(); ++row)
{
for ( ; row < myEntries.get(row)[column]; ++column)
{
/* do stuff */;
}
}
}
这将解决您提出的问题,在某些情况下它可能是合理的。但在你的情况下,它恰好会产生第二个问题(见下一段)。所以我想说有更好的方法(请参阅下面的 "Solution" 部分)。
这在您的情况下不起作用的原因是因为您使用的是 continue <label>
语句。问题是它将完全跳过,从而阻止每个 for
循环的更新语句执行。除非你有 非常 充分的理由使用 continue <label>
或 break <label>
语句,否则 不要't。像这样跳来跳去你的代码会导致各种难以诊断的问题。而且这通常是基本设计错误的标志。
如果您认为必须使用 continue <label>
或 break <label>
语句,那么您可能需要重构(即重新构建代码,这样您就不需要在第一名)。
解决方案
基本上,您想要做的是以下内容的一些变体,以便遍历每一行,并在每一行内遍历每一列:
for (int row = 0; row < myEntries.size(); ++row)
{
for (int column = 0; column < myEntries.get(row).length; ++column)
{
/* do stuff */;
}
}
你的"stuff"在哪里:
if (!isInteger(myEntries.get(row)[column]))
{
mark12Map.put(mark12Line.split(",")[0], myEntries.get(row)[column]);
}
但令人困惑的是,您还必须每行读取并验证一行:
if ((mark12Line = mark12Br.readline()) != null)
{
/* process each column in the row */;
}
所以你把它放在哪里?就在 "row" for
循环内部(这样你就可以为每一行读取一行)并且就在 "column" for
循环外部(因为每一行中都有多个列):
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 */;
}
}
}
这将完成工作,但需要的时间会比需要的时间长。如果我们注意到每当没有更多的行要读取时,我们就可以优化它,那么即使我们还没有达到最大行数,我们也会完成。因此,我们将以下 else
块添加到一行中读取的 if
中:
else
{
break; // break out of outer loop because there are no more lines to read
}
最终解决方案
将以上所有内容放在一起,最终产品如下所示:
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;
}
}
我正在使用 while 和 for 循环遍历文本文件。
我的代码的目标是遍历包含 2 列的 CSV 逗号分隔文本文件,并且仅将字符串解析为地图。我不想要整数,这就是我的程序要做的。
问题是,每次我重新启动 while 循环以转到下一行时,它都会重新启动我的变量并假定它始终在第一行。
这是我的代码:
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;
}
}
}
}
我的代码中发生的事情是,在第一行和第一列,它将它检测为一个整数,因此它不会将该整数放入地图中。第一行第二列是一个字符串,所以放在地图里面。
问题是,一旦完成,它会继续我的 while 循环,并且 row
和 column
都已重置为 0。所以它就像仍在同一行上一样,即使我已将其递增至 row++
和 column++
.
为什么我的整数变量总是重置为 0?我需要他们每次为不同的行递增。
我是说他们错了,还是其他什么破坏了我的代码。
如果您需要更多代码,请告诉我。
感谢您的帮助。
我不确定您是否以最恰当的方式解决了问题,但是回答您错误地声明变量的问题
//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;
}
}
}
}
根据我从您的问题描述和您对 Paul Guiheen 回答的回复中了解到的情况,我认为以下代码可能更接近您的应用程序的预期逻辑:
/* EDITED ...see below */
问题
每次执行外部 while
循环时都会重置 row
和 column
变量,因为它们正在 内部 while
循环。换句话说,每次执行外部 while
循环时,它们将被重新初始化为零。
您可以将它们的初始化 移到 外部 while
循环之外以避免这种情况,如下所示:
int row = 0;
int column = 0;
whileloop: while (/* test something */)
{
for ( ; row < myEntries.size(); ++row)
{
for ( ; row < myEntries.get(row)[column]; ++column)
{
/* do stuff */;
}
}
}
这将解决您提出的问题,在某些情况下它可能是合理的。但在你的情况下,它恰好会产生第二个问题(见下一段)。所以我想说有更好的方法(请参阅下面的 "Solution" 部分)。
这在您的情况下不起作用的原因是因为您使用的是 continue <label>
语句。问题是它将完全跳过,从而阻止每个 for
循环的更新语句执行。除非你有 非常 充分的理由使用 continue <label>
或 break <label>
语句,否则 不要't。像这样跳来跳去你的代码会导致各种难以诊断的问题。而且这通常是基本设计错误的标志。
如果您认为必须使用 continue <label>
或 break <label>
语句,那么您可能需要重构(即重新构建代码,这样您就不需要在第一名)。
解决方案
基本上,您想要做的是以下内容的一些变体,以便遍历每一行,并在每一行内遍历每一列:
for (int row = 0; row < myEntries.size(); ++row)
{
for (int column = 0; column < myEntries.get(row).length; ++column)
{
/* do stuff */;
}
}
你的"stuff"在哪里:
if (!isInteger(myEntries.get(row)[column]))
{
mark12Map.put(mark12Line.split(",")[0], myEntries.get(row)[column]);
}
但令人困惑的是,您还必须每行读取并验证一行:
if ((mark12Line = mark12Br.readline()) != null)
{
/* process each column in the row */;
}
所以你把它放在哪里?就在 "row" for
循环内部(这样你就可以为每一行读取一行)并且就在 "column" for
循环外部(因为每一行中都有多个列):
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 */;
}
}
}
这将完成工作,但需要的时间会比需要的时间长。如果我们注意到每当没有更多的行要读取时,我们就可以优化它,那么即使我们还没有达到最大行数,我们也会完成。因此,我们将以下 else
块添加到一行中读取的 if
中:
else
{
break; // break out of outer loop because there are no more lines to read
}
最终解决方案
将以上所有内容放在一起,最终产品如下所示:
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;
}
}