• 15 апреля стартует «Курс «SQL-injection Master» ©» от команды The Codeby

    За 3 месяца вы пройдете путь от начальных навыков работы с SQL-запросами к базам данных до продвинутых техник. Научитесь находить уязвимости связанные с базами данных, и внедрять произвольный SQL-код в уязвимые приложения.

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

    Запись на курс до 25 апреля. Получить промодоступ ...

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

  • Автор темы vnmukh
  • Дата начала
V

vnmukh

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

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

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

vnmukh

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

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

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

vnmukh

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

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

rrrFer

я заставлял студентов рисовать (если не могут представить)
так должно быть?
не совсем. Теперь первый узел добавится верно, а следующие?
 
V

vnmukh

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

rrrFer

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

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

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

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

vnmukh

А ларчик просто открывался.

C++:
pNode->Next = NULL

Все заработало, спасибо!!
 
R

rrrFer

А ларчик просто открывался.
ага, а эту строку:
Код:
Top->Next = NULL;
теперь можно удалить )
задавайте вопросы и впредь, было не скучно беседовать )
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!