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
Run Code Online (Sandbox Code Playgroud)
当我运行代码时,文件Balance.txt中的最后一行进入无限循环,如何停止无限循环?
不知怎的,这个问题设法被问到了100种不同的方式,其中没有一种与其他方式完全重复.更糟糕的是,每次被问到,它都会得到一些荒谬的错误答案.
要从流中正确读取数据,您需要一个具有单个条件的循环,该循环读取数据并检查该读取尝试是否成功.几乎任何其他东西都容易失败.特别是,几乎不可能得到一个形式的循环:
while (!foo.eof())
Run Code Online (Sandbox Code Playgroud)
要么:
while (!foo.bad())
Run Code Online (Sandbox Code Playgroud)
要么:
while (foo.good())
Run Code Online (Sandbox Code Playgroud)
要么:
while (file)
Run Code Online (Sandbox Code Playgroud)
......实际工作正常 其中每一个都从根本上被打破了.获得正确结果的简便方法是将读取和测试组合到一个操作中,例如:
while (std::getline(somefile, somestring))
Run Code Online (Sandbox Code Playgroud)
要么:
while (file >> a >> b >> c)
Run Code Online (Sandbox Code Playgroud)
至于为什么这些工作和其他工作没有:当文件指针到达文件末尾时,不会立即检测到文件结尾.相反,当您尝试读取某些内容时会检测到它,但文件指针已经在文件的末尾.
因此,当您读取文件中的所有数据时,会发生file.eof()错误.您尝试从文件中读取下一个项目(它失败).然后,即使读取失败,您也会尝试处理数据.
我推荐的表单正确工作的原因是他们尝试读取数据,然后检查是否成功,并在尝试读取失败时立即退出循环,这样他们就不会在读取尝试失败后尝试处理数据.
作为一种独立的(但密切相关的)点:如果您正在尝试读取整个文件,通常不希望在检测文件末尾时特别注意退出循环.只要您可以转换输入,就想要读取,并在失败时立即退出循环.
当/如果在到达文件末尾之前遇到其他错误,这些会有所不同.在这种情况下,专门等待文件结束的循环可以(并且经常会)无限期地继续运行,重复尝试已经失败的操作,但是以未写入循环以正确检测的方式失败.
使用的时候file.eof()是经过你从循环退出,并要检测为何循环退出.如果你已经达到了eof,很棒 - 你只需阅读所有数据.如果您希望循环读取整个文件,但它在到达eof之前退出,那么您可能遇到问题 - 可能是磁盘驱动器出现问题,或者可能只是文件中的错误数据.您通常可以使用file.eof,file.fail并file.bad找出您遇到的错误类型(如果有的话).