C++ Чтение Структуры Из Бинарного Файла

vnmukh

New member
22.08.2012
4
0
#1
Доброго времени суток. Есть программа, создает односвязный список, записывает его в файл, затем читает его из того же файла с последующим вывдом на экран. Создает список и записывает нормально, а вот при считывании вылетает ошибка. Подскажите пожалуйста что не так, заранее спасибо.

C++:
#include <iostream>

using namespace std;

struct Node
{
public:
int value;
int NodeNumber;
Node *Next;
};

class List
{
public:
List();
void Add();
void Add(int val);
void Del();
void ShowAll();
int Save();
int Import();
private:
Node *Top;
int count;
};

List::List()
{
Top = NULL;
}
//вводим с клавиатуры значение поля структуры, добавляем новый узел
void List::Add()
{
int a;
cout << "\nââåäèòå çíà÷åíèå: ";
cin >> a;
Node *pNode = new Node;
pNode->NodeNumber = count;
pNode->value = a;
if(!Top)
{
Top = pNode;
}
else
{
Node *temp = Top;
while (temp->Next) temp=temp->Next;
temp->Next = pNode;
}
}
//тоже добавляем новый узел, только значение поля структуры задается входным параметром
void List::Add(int val)
{
Node *pNode = new Node;
pNode->NodeNumber = count;
pNode->value = val;
if(!Top)
{
Top = pNode;
}
else
{
Node *temp = Top;
while (temp->Next) temp=temp->Next;
temp->Next = pNode;
}
}
//сохраняем список в бинарный файл
int List::Save()
{
Node *current = Top;
FILE *pf = NULL;
pf = fopen("Base", "wb");
if(pf == NULL)
{
cout << "Îøòáêà ôàéëà";
return 0;
}
while(current)
{
fwrite(&(current->value), sizeof(int), 1, pf);
current = current->Next;
}
fclose(pf);
}
//загружаем структуру из бинарного файла
int List::Import()
{
Node *current = Top;
FILE *pf = NULL;
count = 0;
int val;
pf = fopen("Base", "rb");
if(pf == NULL)
{
cout << "Îøèáêà ôàéëà";
return 0;
}
fread(&val, sizeof(int), 1, pf);
while(!feof(pf))
{
cout << " " << val;// в принципе файл открывается, даже выводит значения на экран
Add(val); // но при попытке создать список этим методом вылетает
fread(&val, sizeof(int), 1, pf);
}
fclose(pf);
} 

int menu();

int main()
{
SetConsoleOutputCP(1251);
List l;
bool exit = false;
for(;;)
{
int choice = menu();
switch(choice)
{
case 1:
l.Add();
break;
case 2:
l.ShowAll();
break;
case 3:
l.Del();
break;
case 4:
l.Save();
break;
case 5:
l.Import();
break; 
case 6:
exit=true;
break;
default:
cout << "Íåïðàâèëüíûé ââîä";
break;
}
if(exit) break;
}
return 0;
}

int menu()
{
int a;
cout << "\n******ÌÅÍÞ*******";
cout << "\n(1)Äîáàâèòü";
cout << "\n(2)Ïîêàçàòü âñå";
cout << "\n(3)Óäàëèòü";
cout << "\n(4)Ñîõðàíèòü";
cout << "\n(5)Èìïîðòèðîâàòü";
cout << "\n(6)Âûõîä";
cin >> a;
return a;
}
P.S. За код строго не судите я не волшебник, я только учусь
 
R

rrrFer

#2
не пытался вникнуть.
Мне не нравится это:
Код:
 Node *pNode = new Node;
pNode->NodeNumber = count;
pNode->value = val;
->next Не инициализируется, но используется: while (temp->Next) temp=temp->Next;
 

vnmukh

New member
22.08.2012
4
0
#3
-> next инициализируется

C++:
	Node *pNode = new Node; // создаем новый узел списка  
pNode->NodeNumber = count;
pNode->value = val;
if(!Top)  // если до этого узлов нет
{
Top = pNode; // созданный узел становится головным
}
else
{
Node *temp = Top; 
while (temp->Next) temp=temp->Next; //иначе движемся по связям temp=temp->Next
temp->Next = pNode; //когда доходим до последнего узла, привязываем к его ->next созданный узел
//здесь ->Next и инциализируется									
}
как-то так, добавление узла работает нормально
 
R

rrrFer

#4
нет
когда добавляется первый узел списка - то его указатель next Должен быть равен нулю, при этом выполнится этот код:
Код:
	Node *pNode = new Node; // создаем новый узел списка  
pNode->NodeNumber = count;
pNode->value = val;
if(!Top)  // если до этого узлов нет
{
Top = pNode; // созданный узел становится головным
}
где тут инициализация?

поэтому для всех последующих добавляемых элементов while (temp->Next) не имеет смысла - по указателю мусор
 

vnmukh

New member
22.08.2012
4
0
#5
переделал
C++:
if(!Top)
{
Top = pNode;
Top->Next = NULL;
}
так должно быть?

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

vnmukh

New member
22.08.2012
4
0
#7
следующие будут проходить по связям temp = temp->Next до конца, то есть пока Next не будет равен NULL, затем присвоит последенему указателю Next, который NULL значение pNode
 
R

rrrFer

#8
то есть пока Next не будет равен NULL
у них Next Не инициализирован, там хранится мусор сравнивать который ни с чем не корректно.

допустим я хочу список из элементов 1, 2, 3, у вас работает так:
1 -> NULL
1 -> 2 -> МУСОР
1 -> 2 -> ??? пытаюсь сравнить мусор с нулем, с большой веротяностью мусор не равен нулю, поэтому в мусоре я ищу указатель Next и его опять сравниваю.... это явно ошибка.

Нарисуй список и посмотри что там происходит.

а вот при считывании вылетает ошибка.
как-то так, добавление узла работает нормально
а что тогда не работает? ) ""
"при считывании" ты и пытаешься добавлять элементы в список этой негодной функцией.
 

vnmukh

New member
22.08.2012
4
0
#9
А ларчик просто открывался.

C++:
pNode->Next = NULL
Все заработало, спасибо!!