I'm somewhat new to programming, so I'm not sure how to search for this problem, and I know I asked 2 other questions about this, but I can't seem to make it work.
I got a problem, where I have a vector:
vector<Device*> Devicelist_;
Whhere I try to load Devices into using this function (I already made a Save-function, which works):
bool Devicelist::LoadFromFile() //Opdaterer vector<Device> fra fil
{
ifstream LoadFile("Devices.dat", ios::in | ios::binary);
if (!LoadFile)
{
cerr << "File could not be opened." << endl;
return false;
}
LoadFile.seekg(0, ios::end);
int numberOfDevices = LoadFile.tellg() / sizeof(Device);
for (int i = 0; i < numberOfDevices; i++)
{
Devicelist_.push_back(new Device);
LoadFile.read(reinterpret_cast<char *>(Devicelist_[i]), sizeof(Device));
}
cout << Devicelist_[0]->getName() << endl;
LoadFile.close();
return true;
}
The problem is that LoadFile.read()
does not load any Devices into the devicelist.
Can you see what my problem is? Thanks in advance.
Your problem is actually really simple. You forgot to reset your get position:
LoadFile.seekg(0, ios::end);
int numberOfDevices = LoadFile.tellg() / sizeof(Device);
for (int i = 0; i < numberOfDevices; i++)
should be
LoadFile.seekg(0, ios::end);
int numberOfDevices = LoadFile.tellg() / sizeof(Device);
LoadFile.seekg(0L, ios::beg);
for (int i = 0; i < numberOfDevices; i++)
An alternative to finding the number is using stat:
#include <sys/stat.h>
int getNumberOfDevices(char *filename)
{
struct stat st;
return st.st_size / sizeof(Device);
}
or, if you wanted to avoid stat, you could do something like this:
bool Devicelist::LoadFromFile() //Opdaterer vector<Device> fra fil
{
ifstream LoadFile("Devices.dat", ios::in | ios::binary);
if (!LoadFile)
{
cerr << "File could not be opened." << endl;
return false;
}
int numberOfDevices = 0;
while (true)
{
Device *tmp = new device;
LoadFile.read(reinterpret_cast<char *>(tmp), sizeof(Device));
if (LoadFile.good()) //we successfully read one
{
++numberOfDevices;
Devicelist_.push_back(tmp);
}
else break; //get out of the infinite loop
}
cout << Devicelist_[0]->getName() << endl;
LoadFile.close();
return true;
}
This way, it reads all of them, without messing around with positions, and keeps a count when it is finished.
This line
LoadFile.seekg(0, ios::end);
puts the file at the end of the file. You need to put it back at the start by
LoadFile.seekg(0, ios::beg);
Update
You can make the code simpler by saving the number of Device
s at the top of the file. Then, you can use:
int numberOfDevices = 0;
LoadFile.read(&numberOfDevies, sizeof(int));
for (int i = 0; i < numberOfDevices; i++)
There won't be any need to get the size of the file to deduce the number of Device
s.
The other alternative is the one suggested by @phyrrus9 where you keep reading the Device
s until there are no more Device
s to read from the file.