c++ EOF运行过多次

c++ EOF running one too many times?

本文关键字:运行 EOF c++      更新时间:2023-10-16

这是我第一次使用EOF和/或文件,我有一个问题,我的代码挂起,我认为这是因为我的EOF循环了太多次。

我从一个文件中输入,并以这种方式动态地创建对象,一旦文件运行,它就会挂起。

        while( !studentFile.eof() )
    {
        cout << "38n";
        Student * temp = new Student();
        (*temp).input( studentFile );
        (*sdb).insert( (*temp) );           
    }

这段代码就是要讨论的代码。count>> "38n";是行号,我认为它是因为循环次数太多而挂起的。

文件只包含4个学生的数据值,但38出现了5次,这就是我认为它循环次数太多的原因;一旦它得到最后一位数据,它似乎没有注册到文件已经结束,并再次循环,但是没有数据输入,所以我的代码挂起。

如何解决这个问题?我的逻辑正确吗?

谢谢。

其他人已经指出了您注意到的问题的细节。

然而,你应该意识到,还有更多的问题你还没有注意到。一个是相当明显的内存泄漏。循环的每次迭代都执行:Student * temp = new Student();,但永远不会执行匹配的delete

c++使内存管理比其他一些语言(例如Java)简单得多,这些语言要求您对使用的每个对象进行new。在c++中,你可以定义一个对象并使用它:

Student temp;
temp.input(studentFile);

这简化了代码并消除了内存泄漏——您的Student对象将在每次迭代结束时自动销毁,并在下一个迭代开始时创建一个(概念上的)新的/不同的对象。

虽然它本身并不是一个bug ,但是它仍然可以被简化很多。因为无论sdb指向什么,显然都有insert成员函数,您可以像使用标准容器一样使用它(它实际上可能是,尽管这两种方式都无关紧要)。为了整理代码,首先为Student编写一个提取操作符:

std::istream &operator>>(std::istream &is, Student &s) {
    s.input(is);
    return is;
}

然后你可以把数据从流复制到集合:

std::copy(std::istream_iterator<Student>(studentFile),
          std::istream_iterator<Student>(),
          std::inserter(*sdf));

请注意,这会自动正确处理EOF,因此您根本不必处理像开始时那样的问题(即使您希望引起这些问题,这也不容易)。

这是因为EOF标志只在之后设置,您尝试读取但未获得数据。输入

Test for EOF -> No EOF
Try to read one line -> Good, read first line
Test for EOF -> No EOF
Try to read one line -> Good, read second line
Test for EOF -> No EOF
Try to read one line -> Good, read third line
Test for EOF -> No EOF
Try to read one line -> Good, read fourth line
Test for EOF -> No EOF
Try to read one line -> EOF

但是在Try to read one line -> EOF中,在第五次迭代时,您已经在while的主体中,这就是为什么您看到循环运行了5次。所以在检查EOF之前需要先阅读

在对流执行操作后,需要立即检查流状态位。您没有显示代码,但是看起来(*temp).input(studentFile)正在从流中读取数据。调用eof()(或其他状态检查)读取之后,但在处理您(试图)读取的数据之前