So what I'm trying to do is to save a linked list, like the one bellow, in a binary file so in case that the program crashes or something, I don't have to re-add all the nodes that I previously added, the thing is I don't have the slightest clue on how to do this
How can i apply hero to my list, do i have to do one of those loops for each variable in the node? And im guessing that id also need to do it for each node in the list.
how about reading from the file?
then your code for writing to a binary file could look like
Not in this case because of those two C++ strings in the node class.
Also you should start using C++ style casts, they are safer (if one can say any cast is safe).
how about reading from the file?
If you must use binary files, I recommend you start by getting the "writing" correct. But if binary files are not a "must use" you should really consider sticking with normal text files.
// Read and write a string
bool readString(istream &is, string &str)
{
// a string is the size followed by the data
size_t sz;
is.read(reinterpret_cast<char*>(&sz), sizeof(sz));
str.resize(sz);
is.read(const_cast<char*>(str.data()), sz); // might not be portable
return is.good();
}
bool writeString(ostream &os, string &str)
{
// a string is the size followed by the data
size_t sz = str.size();
os.write(reinterpret_cast<char*>(&sz), sizeof(sz));
os.write(const_cast<char*>(str.data()), sz); // might not be portable
return os.good();
}
// Read and write a node. This does NOT change the next pointer
bool product_node::read(istream &is)
{
readString(is, name);
readString(is, brand);
is.read(reinterpret_cast<char*>(&productCode), sizeof(productCode));
// ADD CODE TO READ THE OTHER MEMBERS
return is.good();
}
bool product_node::write(ostream &os)
{
writeString(os, name);
writeString(os, brand);
os.write(reinterpret_cast<char*>(&productCode), sizeof(productCode));
// ADD CODE TO WRITE THE OTHER MEMBERS
return os.good();
}
// Read and write a list. Each node is written as a bool (true), followed'
// by the record. When bool is false, that indicates the end of the list.
bool product_list:read(istream &is)
{
// ADD CODE TO READ THE LIST. Use product_node::read() to read
// individual records
return is.good();
}
bool product_list::write(ostream &os)
{
// ADD CODE TO READ THE LIST. Use product_node::write() to write
// individual records
return os.good();
}
But remember if your class has non-trivial constructed member variables you must write out each member variable one at a time. For example you can't directly write a std::string, you must first write the "length" of the string, then write the std::string.c_str() of that variable. Remember that a std::string is not a fixed length, and the data is "hidden" in basically as a pointer. So if you just write the std::string you actually write out a pointer, not the actual data.
josilva00, could you tell why it's not allowed to do reading and writing in text mode? That makes no sense to me, at least not for your data that you have to store.
you can't directly write a std::string, you must first write the "length" of the string, then write the std::string.c_str() of that variable.
I got bit by that when I was converting an older "save C string data" bit of code to "save std::string" by just writing the std::string to the file. It worked to save and retrieve some test data, until I changed the data. *CRASH, BANG, BOOM* Ooops!
i opened the binary file after writing to it and its empty
Did you close the output file before opening the input file? Did product_list::write() return true?
How do i read and fill the the list?
You can't with that write() code because there's no way to tell when you hit the end of the list. That's why my read() method had this comment:
1 2
// Read and write a list. Each node is written as a bool (true), followed
// by the record. When bool is false, that indicates the end of the list.
You need to write the bool. That way when you're reading the list, you know when to stop.
An alternative is to make one pass through the list, counting the items. They write the count, followed by all the items (without the bool). When reading , you read the count, and then read exactly that many items.
Oh, and a bonus: when reading the list, you should clear any contents in it first.