Click here to Skip to main content
15,885,767 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have problem with reading bin file to binary tree. `SaveFile` function is not probably fine but the `readFile` function is the problem.For example,I save 3 nodes to the .bin file, and when I read the file back , A node that I did not write to file shows up.I mean there is a node added to the binary tree when I try to read it from file. I don't think that it stop when it's `EOF`. I may read again one time when it's `EOF`.
I need help with reading data to memory, yet saving data to binary file is still not sure because I don't which one of those 2 function causes the problem.
could you help me?

//Read file to memory
void readFile(Node *&root, ifstream &file)
{
file.seekg(0, ios::end);

if (file.tellg() == 0)
cout << "File is empty!" << endl;
else
{
file.seekg(0, ios::beg);

while(!file.eof())
{
Node *newNode = new Node;

file.read((char*)&newNode->data, sizeof(Person));
insertNode(root,newNode);

}
cout << "File was loaded.\n";
}
}

void saveFile(Node *root, ofstream &file)
{
if (root != NULL)
{
file.write((char*)&root->data,sizeof(Person));

saveFile(root->Left, file);
saveFile(root->Right, file);
}
}

void insertNode(Node *&root, Node *newNode)
{
newNode->Left = NULL;
newNode->Right = NULL;

if (root == NULL) root = newNode;
else
{
Node *curr = root;

while (true)
{
if (newNode->data.Id < curr->data.Id)
{
if (curr->Left != NULL)
curr = curr->Left;
else
{
curr->Left = newNode;
break;
}
}
else if (curr->Right != NULL)
curr = curr->Right;
else
{
curr->Right = newNode;
break;
}
}

}
}

What I have tried:

I try changing the readFile function many time;however, I din not work at all.
Posted
Updated 19-May-17 3:21am

Start by checking your save file with a hex editor, and making sure that what you think it contains is exactly what it does hold. Until you have made completely sure that the file that your readFile function is processing is complete, valid, and perfect, you can't even begin to debug the readFile function itself! And when you say "`SaveFile` function is not probably fine" it implies that you have no real idea what is in the file. And since we have no idea what is in your Person struct, the chances are very good that what you write to the file is not what you think it should be.

When you have that correct, use the debugger to read it back line by line and check exactly what it is doing at each stage. It should be obvious what the problem is if you debug it carefully!
 
Share this answer
 
You did not show us the most important code part: The definition of your Node class.

This indicates that Node.data is of type Person:
file.write((char*)&root->data,sizeof(Person));

When the Person class contains any members that are pointers to allocated memory, writing and reading the way you are doing it will not work.

If it looks for example like
C++
struct Person
{
    int id;
    char name[MAX_NAME_LEN];
};
all should be fine. Then do what OriginalGriff suggested.

But if it looks for example like
C++
struct Person
{
    int id;
    std::string name;
};
you have to write the content of the name member. Your code would only write the memory address (32 or 64 bit value). Reading that later from file will then point to invalid memory.

In the case of strings you can write the length of the string first followed by the content:
C++
// Write the ID
file.write((char*)&root->data.id, sizeof(Node.data.id));
// Get length of name and write it
size_t len = root->data.name.length();
file.write((char*)&len, sizeof(len));
// Write the string content
file.write(root->data.name.c_str(), len);

When reading you have to do it the same way:
Node *newNode = new Node;
// Read the ID
file.read((char*)&newNode->data.id, sizeof(Node.data.id));
// Read the length of the name
size_t len;
file.read((char*)&len, sizeof(len));
// Allocate buffer for name, read name and assign
char name = new char[len];
file.read(name, len);
newNode->data.name.assign(name, len);
// Delete the buffer
delete [] name;

Alternatively you may also write strings with a NULL terminator. But that requires reading character by character until the NULL byte is read.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900