1

Im writing a vector of size three and when i read i get a vector of size 4 with the last index being a duplicate of the index 2.

Heres my code.

void IOManager::WriteBin(const string &filename, vector<userRank> highScorers, int rank) {

    ofstream fsalida(filename, ios::out | ios::binary); 

    if (fsalida.is_open())
    {
        for (int i = 0; i < highScorers.size();i++) {
            fsalida.write(reinterpret_cast<char*>(&highScorers[i]), sizeof(highScorers[i]));

        }
        //highScorers.size() is 3
        fsalida.close();      

    }else cout << "Unable to open file for writing\n";
}

vector<userRank> IOManager::ReadBin(const string &filename) {

    ifstream fentrada(filename, ios::in | ios::binary); 

    if (fentrada.is_open())
    {

        vector<userRank>bestPlayers;

        for (int i = 0; fentrada.good(); i++) {
            userRank tempUser;
            fentrada.read(reinterpret_cast<char*>(&tempUser), sizeof(tempUser));
            bestPlayers.push_back(tempUser);

        }
        //bestPlayers.size() is 4!!!!!! Im losing my mind
        fentrada.close();

        return bestPlayers;

    }
    else cout << "Unable to open file for reading\n";   

}

Here's my UserRank struct

struct userRank
{
    char userName [5];
    int score;  
};

A wild userRank apperars for some reason, does anybody know why?

PauBlanes
  • 11
  • 4
  • 2
    I'm not sure what exactly you want. And you didn't post all necessary for me to understand your code. But I'll take a wild guess that you should read this: [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). – giusti Jan 05 '17 at 16:59
  • This isn't the problem, but the calls to `fsalida.close()` and `fentrada.close()` aren't needed. The stream's destructor will close the file. – Pete Becker Jan 05 '17 at 17:00
  • In the first loop, it is guaranteed you are writing `highScorers.size()` items, but in the read loop, you are looping depending on the stream flag's condition. Why not do an experiment and read the same number of data you wrote by hardcoding the second loop with the number of items. – PaulMcKenzie Jan 05 '17 at 17:03
  • BTW, your `ReadBin` method still needs to return a value when the file is not opened. All return paths need to return a value. There should be some indication returned to the caller that the function failed. – Thomas Matthews Jan 05 '17 at 17:05
  • It is because you don't check after the read to ensure it actually was able to read. Since it couldn't read further it didn't put data into the memory allocated to tempUser, it used the same local variable so the memory wasn't released, and pushed the old value onto the vector. You have to check the result of the read before trying to push onto the vector, especially when reading a stream. – MiltoxBeyond Jan 05 '17 at 17:08
  • @MiltoxBeyond ty, but how can i check if it read successfully? – PauBlanes Jan 05 '17 at 17:19

1 Answers1

0

I suggest reorganizing the read function:

userRank tempUser;
for (int i = 0;
     fentrada.read(reinterpret_cast<char*>(&tempUser), sizeof(tempUser));
     i++)
{
    bestPlayers.push_back(tempUser);
}

Search the internet for "stackoverflow c++ why eof in while is bad".

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154