Member 13210661 Ответов: 2

Файл bin в двоичном дереве


У меня есть проблема с чтением файла bin в двоичное дерево. Функция "SaveFile", вероятно, не очень хороша, но функция "readFile" - это проблема.Например, я сохраняю 3 узла в файл. bin , и когда я читаю файл обратно, появляется узел, который я не записывал в файл.Я имею в виду, что есть узел, добавленный в двоичное дерево, когда я пытаюсь прочитать его из файла. Я не думаю, что он остановится, когда это будет "ЭОФ". Я могу прочитать снова один раз, когда это будет "EOF".
Мне нужна помощь с чтением данных в память, но сохранение данных в двоичный файл все еще не уверен, потому что я не знаю, какая из этих 2 функций вызывает проблему.
не могли бы вы мне помочь?

// Чтение файла в память
void readFile(Node * & amp; root, ifstream & file)
{
файл.seekg(0, ios:: end);

если (файл.tellg() == 0)
cout << "файл пуст!" < & lt; endl;
ещё
{
файл.seekg(0, ios:: beg);

хотя(!файл.ВФ())
{
Узел *newNode = новый узел;

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

}
cout < & lt; "файл был загружен.\северный";
}
}

void saveFile (Node *root, ofstream & file)
{
if (root != NULL)
{
файл.писать (к(char*)&ампер;корень-&ГТ;данных,оператор sizeof(человек));

saveFile (root - & gt;Left, file);
saveFile (root - & gt;Right, файл);
}
}

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

if (root = = NULL) root = newNode;
ещё
{
Узел * curr = корень;

в то время как (правда)
{
if (newNode- & gt;data.ИД &ЛТ; ту-и GT;сведения.Идентификатор)
{
if (curr- & gt;Left != NULL)
curr = curr - & gt;слева;
ещё
{
curr- & gt;Left = newNode;
перерыв;
}
}
else if (curr- & gt;Right != NULL)
curr = curr - & gt;справа;
ещё
{
curr- & gt;Right = newNode;
перерыв;
}
}

}
}

Что я уже пробовал:

Я много раз пытаюсь изменить функцию readFile,но у меня ничего не получается.

2 Ответов

Рейтинг:
7

Jochen Arndt

Вы не показали нам самую важную часть кода: определение вашего Node класс.

Это указывает на то, что Node.data иметь тип Person:

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

Когда Person класс содержит любые члены, которые являются указателями на выделенную память, запись и чтение так, как вы это делаете, не будут работать.

Если это выглядит например так
struct Person
{
    int id;
    char name[MAX_NAME_LEN];
};
все должно быть хорошо. Тогда что делать OriginalGriff предложенный.

Но если это выглядит например так
struct Person
{
    int id;
    std::string name;
};
вы должны написать содержание name член. Ваш код будет записывать только адрес памяти (32 или 64-битное значение). Чтение этого позже из файла будет указывать на недопустимую память.

В случае строк вы можете сначала записать длину строки, а затем ее содержимое:
// 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);

При чтении вы должны делать это точно так же:
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;

В качестве альтернативы вы также можете писать строки с нулевым Терминатором. Но это требует чтения символа за символом, пока не будет прочитан нулевой байт.


Рейтинг:
20

OriginalGriff

Начните с проверки вашего файла сохранения с помощью шестнадцатеричного редактора и убедитесь, что то, что вы думаете, что он содержит, именно так то, что он держит. Пока вы полностью не убедитесь, что файл, который обрабатывает ваша функция readFile, является полным, действительным и совершенным, вы даже не можете начать отлаживать саму функцию readFile! И когда вы говорите "функция' SaveFile`, вероятно, не в порядке", это означает, что вы не имеете реального представления о том, что находится в файле. И поскольку мы понятия не имеем, что находится в вашей личной структуре, очень велика вероятность того, что то, что вы пишете в файл, не то, что вы думаете, что это должно быть.

Когда вы сделаете это правильно, используйте отладчик, чтобы прочитать его обратно строка за строкой и точно проверить, что он делает на каждом этапе. Должно быть очевидно, в чем проблема, если вы тщательно отладите ее!