void ReadTheData(ifstream& in_stream, ofstream& out_stream)
{
using namespace std;
int id;
char name[100] = "";
double balance;
in_stream >> id >> name >> balance;
while(name[0] || ! in_stream.eof()) // Continue looping until eof or name is not present.
{
cout << id << '\t' << name << '\t' << balance << endl;
in_stream >> id >> name >> balance;
}
}
the Balance.txt has format style:
4248749 Kelly_E 460.02
8898693 Kelly_George_MD 1764.68
4597789 Lambert_Richard 1571.79
当我运行代码时,文件Balance.txt中的最后一行进入无限循环,如何停止无限循环?
答案 0 :(得分:7)
不知怎的,这个问题设法被问到100种不同的方式,其中没有一种完全与其他方式重复。更糟糕的是,每次被询问时,它都会得到一些荒谬的坏答案。
要从流中正确读取数据,您需要一个具有单个条件的循环,该条件读取数据和检查该读取尝试是否成功。几乎任何其他东西都容易失败。特别是,几乎不可能得到一个形式的循环:
while (!foo.eof())
或:
while (!foo.bad())
或:
while (foo.good())
或:
while (file)
......实际工作正常。其中每一个都从根本上被打破了。获得正确结果的简便方法是将读取和测试结合到一个操作中,例如:
while (std::getline(somefile, somestring))
或:
while (file >> a >> b >> c)
为什么这些工作和其他人不在文件指针到达文件末尾时立即检测到文件结尾 。相反,当您尝试读取某些内容时会检测到它,但文件指针已经在文件的末尾。
因此,当您读取文件中的所有数据时,file.eof()
仍为假,会发生什么。您尝试从文件中读取下一个项目(它失败)。然后,即使读取失败,您也会尝试处理数据。
我推荐的表单正确工作的原因是他们尝试读取数据,然后检查是否成功,如果尝试读取失败则立即退出循环,因此他们不尝试处理读取尝试失败后的数据。
作为一种独立的(但密切相关的)点:如果您正在尝试读取整个文件,那么不通常希望以检测结束为基础退出循环的文件。只要您可以转换输入,就想要读取,并在失败时立即退出循环。
如果在到达文件末尾之前遇到某些其他错误,则会有所不同。在这种情况下,专门等待文件结束的循环可以(并且经常会)无限期地继续运行,重复尝试已经失败的操作,但是以不能正确检测循环的方式失败
如果你已经达到了eof,那就太棒了 - 你只需阅读所有数据。如果您希望循环读取整个文件,但它在到达eof之前退出,那么您可能遇到问题 - 可能是磁盘驱动器出现问题,或者可能只是文件中的错误数据。您通常可以使用file.eof()
,file.eof
和file.fail
来解决您遇到的错误(如果有的话)。
答案 1 :(得分:1)
当您尝试使用
阅读时in_stream >> id >> name >> balance;
在阅读完最后一行后,最有可能设置failbit
和eofbit
。您可以使用istream::good()
来检测istream
是否仍处于有效状态。
更改行
while(name[0] || ! in_stream.eof())
到
while(in_stream.good())
或
while(in_stream)