c ++ EOF运行一次太多次?

时间:2011-11-23 00:49:58

标签: c++ file-io hang eof dynamic-allocation

这是我第一次使用EOF和/或文件,而我遇到的问题是我的代码挂起,我相信这是因为我的EOF循环次数太多了。

我从文件中输入,并以这种方式动态创建对象,并在文件运行后挂起。

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

        (*sdb).insert( (*temp) );           
    }

这段代码是有问题的代码。 cout&gt;&gt; “38 \ n” 个;是行号和我认为它多次循环的原因。

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

我该如何解决这个问题?我的逻辑是否正确?

谢谢。

3 个答案:

答案 0 :(得分:3)

这是因为在尝试读取并且没有数据之后,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之前阅读。

答案 1 :(得分:3)

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

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

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

Student temp;

temp.input(studentFile);

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

虽然它本身并不是一个真正的错误 ,但即便如此仍然可以简化。因为显然有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,因此您无需像开始时那样处理问题(即使您想要引起它们,也不容易)。

答案 2 :(得分:0)

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