ifstream 无缘无故失败?

发布于 2024-11-09 18:47:25 字数 1792 浏览 2 评论 0原文

我有一个 3d 球体列表,当我保存列表时,我循环:

void Facade::Save(std::ostream& fs)
{
    fs<<x<<" "<<y<<" "<<z<<" "<<r<<" "; //save fields
    fs<<color[0]<<" "<<color[1]<<" "<<color[2]<<std::endl;
}

当我恢复列表时,我使用:

    void Facade::Load(std::ifstream& fs, BallList* blist)
    {
        GLfloat c[3];
        fs>>x>>y>>z>>r;
        //fails there, why
        fs>>c[0]>>c[1]>>c[2];
        .....   
    }

我不知道出了什么问题,但是在读取最后一行时,最后一行的颜色分量无法读取球体,读取最后一个球体的半径后流失败。我检查了球体列表文件:

7.05008 8.99167 -7.16849 2.31024 1 0 0
3.85784 -3.93902 -1.46886 0.640751 1 0 0
9.33226 3.66375 -6.93533 2.25451 1 0 0
6.43361 1.64098 -6.17298 0.855785 1 0 0
6.34388 -0.494705 -6.88894 1.50784 1 0 0 

这看起来不错。有人能告诉我为什么会发生这种情况吗?这是ifstream的bug吗? 顺便说一句,我正在使用 Unicode。


循环附在下面:

void BallList::Load(std::istream& fs)
{
    Clear();
    Facade ball1;
    while(!fs.fail() && !fs.eof())
    {
        ball1.Load(fs, this);
        Add(ball1);
    }
    /*
    balls.pop_back(); //this is a work around, get rid of the last one
    originalballs.pop_back();
    */
}

void BallList::Save(std::ostream& fs)
{
    vector<Facade>::iterator itero = this->originalballs.begin();
    while (itero != this->originalballs.end())
    {
        itero->Save(fs);
        itero++;
    }

    /*
    //work around the ifstream problem: the color of the last sphere cannot be read
    //add a dummy item as the last
    itero = this->originalballs.begin();
    if(itero != this->originalballs.end())
    {
        itero->Save(fs);
    }
    */
}

I have a list of 3d spheres, when I save the list, I loop through:

void Facade::Save(std::ostream& fs)
{
    fs<<x<<" "<<y<<" "<<z<<" "<<r<<" "; //save fields
    fs<<color[0]<<" "<<color[1]<<" "<<color[2]<<std::endl;
}

and when I restore the list, I use:

    void Facade::Load(std::ifstream& fs, BallList* blist)
    {
        GLfloat c[3];
        fs>>x>>y>>z>>r;
        //fails there, why
        fs>>c[0]>>c[1]>>c[2];
        .....   
    }

I don't know what goes wrong, but when reading the last line, the color components of the last sphere cannot be read, the stream fails after reading the radius of the last sphere. I checked the sphere list file:

7.05008 8.99167 -7.16849 2.31024 1 0 0
3.85784 -3.93902 -1.46886 0.640751 1 0 0
9.33226 3.66375 -6.93533 2.25451 1 0 0
6.43361 1.64098 -6.17298 0.855785 1 0 0
6.34388 -0.494705 -6.88894 1.50784 1 0 0 

This looks good. Can somebody tell me why is this happening? Is this a bug of ifstream?
I'm using Unicode by the way.


The loops are attached below:

void BallList::Load(std::istream& fs)
{
    Clear();
    Facade ball1;
    while(!fs.fail() && !fs.eof())
    {
        ball1.Load(fs, this);
        Add(ball1);
    }
    /*
    balls.pop_back(); //this is a work around, get rid of the last one
    originalballs.pop_back();
    */
}

void BallList::Save(std::ostream& fs)
{
    vector<Facade>::iterator itero = this->originalballs.begin();
    while (itero != this->originalballs.end())
    {
        itero->Save(fs);
        itero++;
    }

    /*
    //work around the ifstream problem: the color of the last sphere cannot be read
    //add a dummy item as the last
    itero = this->originalballs.begin();
    if(itero != this->originalballs.end())
    {
        itero->Save(fs);
    }
    */
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

假面具 2024-11-16 18:47:25

我预计在正确读取 5 个球(球体)后会失败。

该循环的设计使得尝试读取第 6 个球将会失败,但 Add() 仍会被调用!
你应该重新定义你的代码:

std::ifstream& Facade::Load(std::ifstream& fs, BallList* blist)
{
    GLfloat c[3];
    fs>>x>>y>>z>>r;        // This will fail if there is no input.
                           // Once all 5 balls have been read
                           // There is only a new line character on the stream.
                           // Thus the above line will fail and the fail bit is now set.
    fs>>c[0]>>c[1]>>c[2];

    return fs;  // returned so it can be tested in loop.
}

void BallList::Load(std::istream& fs)
{
    Clear();
    Facade ball1;
    while(ball1.Load(fs, this))  // Only enter loop if the load worked
    {                            // Load worked if the stream is in a good state.
        // Only call Add() if Load() worked.
        Add(ball1);
    }
}

PS。空白是你的朋友。我个人认为这样更容易阅读:

    fs >> x >> y >> z >> r;

I would expect this to fail after reading 5 balls (spheres) correctly.

The loop is designed so that attempting to read the 6th ball will fail but Add() is still called!!
You should redefine your code a bit:

std::ifstream& Facade::Load(std::ifstream& fs, BallList* blist)
{
    GLfloat c[3];
    fs>>x>>y>>z>>r;        // This will fail if there is no input.
                           // Once all 5 balls have been read
                           // There is only a new line character on the stream.
                           // Thus the above line will fail and the fail bit is now set.
    fs>>c[0]>>c[1]>>c[2];

    return fs;  // returned so it can be tested in loop.
}

void BallList::Load(std::istream& fs)
{
    Clear();
    Facade ball1;
    while(ball1.Load(fs, this))  // Only enter loop if the load worked
    {                            // Load worked if the stream is in a good state.
        // Only call Add() if Load() worked.
        Add(ball1);
    }
}

PS. White space is your friend. Personally I think this is easier to read:

    fs >> x >> y >> z >> r;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文