将bin文件读取到二叉树 [英] Read bin file to binary tree

查看:75
本文介绍了将bin文件读取到二叉树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将bin文件读取到二叉树时遇到问题。 `SaveFile`函数可能不错,但`readFile`函数是问题。例如,我将3个节点保存到.bin文件中,当我读回文件时,我没有写入文件的节点出现我的意思是当我尝试从文件中读取它时,在二叉树中添加了一个节点。当它是'EOF`时,我认为它不会停止。我可能会再读一遍它的'EOF`。

我需要帮助将数据读取到内存中,但是将数据保存到二进制文件仍然不确定,因为我没有那两个功能中的哪一个导致问题。

你可以帮帮我吗?



//将文件读入内存

void readFile(Node *& root,ifstream& file)

{

file.seekg(0,ios :: end);



if(file.tellg()== 0)

cout<< 文件是空的! << endl;

else

{

file.seekg(0,ios :: beg);



while(!file.eof())

{

节点* newNode =新节点;



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

insertNode(root,newNode);



}

cout<< 文件已加载。\ n;

}

}



void saveFile(Node * root ,ofstream& file)

{

if(root!= NULL)

{

file.write ((char *)& root-> data,sizeof(Person));



saveFile(root-> left,file);

saveFile(root->右,文件);

}

}



无效insertNode(Node *& root,Node * newNode)

{

newNode-> Left = NULL;

newNode-> Right = NULL;



if(root == NULL)root = newNode;

else

{

节点* curr = root;



while(true)

{

if (newNode-> data.Id< curr-> data.Id)

{

if(curr-> Left!= NULL)

curr = curr->左;

其他

{

curr->左= newNode;

休息;

}

}

否则if(curr-> Right!= NULL)

curr = curr->对;

其他

{

curr-> Right = newNode;

break;

}

}



}

}



我尝试了什么:



我尝试多次更改readFile函数;但是,我din不工作。

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.

推荐答案

首先用十六进制编辑器检查你的保存文件,并确保你认为它包含的是 完全 它的作用。在您完全确定readFile函数正在处理的文件是完整,有效和完美之前,您甚至无法开始调试readFile函数本身!当你说`SaveFile`函数可能不太好时,它暗示你并不知道文件中的内容。因为我们不知道你的Person结构中有什么,所以你写入文件的内容不是你认为的应该是非常好的。



如果你有正确的话,可以使用调试器逐行读取它,并确切地检查它在每个阶段的作用。如果你仔细调试它应该是显而易见的问题!
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!


你没有向我们展示最重要的代码部分:节点的定义 class。



这表示 Node.data 的类型为

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));



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

struct Person
{
    int id;
    char name[MAX_NAME_LEN];
};

一切都应该没问题。然后做什么 OriginalGriff 建议。



但如果它看起来像

all should be fine. Then do what OriginalGriff suggested.

But if it looks for example like

struct Person
{
    int id;
    std::string name;
};

您必须编写名称成员的内容。您的代码只会写入内存地址(32或64位值)。稍后从文件中读取将指向无效的内存。



对于字符串,您可以先写入字符串的长度,然后是内容:

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:

// 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;



或者你也可以使用NULL终止符编写字符串。但是这需要逐个字符地读取,直到读取NULL字节为止。


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


这篇关于将bin文件读取到二叉树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆