если поток не работает без причины? - PullRequest
0 голосов
/ 26 мая 2011

У меня есть список 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? Кстати, я использую 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);
    }
    */
}

1 Ответ

4 голосов
/ 26 мая 2011

Я ожидаю, что это не получится после правильного чтения 5 шаров (сфер).

Цикл разработан таким образом, что попытка прочитать шар 6 th не удастся, но 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;
...