Cześć, mam problem z zapisem elementu stosu na dysk w plik binarny. Według specyfikacji stos podczas zapisu pownien być odzielony od danych
oraz nie powinien nic wiedziec o typie danych natomiast nie rozumiem jak mam odzielić stos od danych dzięki czemu potem mógłbym go odczytać.
Myślałem o czymś takim podczas zapisu w pliku my_stack.c:
void MY_STACK_SaveToFile(const char *filename)
{
FILE* pf = fopen(filename, "wb");
if (!pf)
{
MessageToScreen(ERR_NUMB_OPEN_FILE);
}
MY_STACK* p = first;
while (p)
{
fwrite(p->pData, sizeof(p->pData), 1, pf);
p = p->next;
}
fclose(pf);
}
Stack.c
#include <stdlib.h>
#include <stdio.h>
#include <tchar.h>
#include "stdafx.h"
#include "my_interface.h"
#include "my_stack.h"
#include "my_student.h"
#include "error_handling.h"
int _tmain(int argc, _TCHAR* argv[])
{
MessageToScreen(COM_NUMB_START);
MY_STACK_Init(MY_STUDENT_Free);
size_t op = 0;
while (op >= INTERF_PUSH && op <= INTERF_STOP)
{
menu();
scanf("%d", &op);
switch (op)
{
case INTERF_PUSH: push();
break;
case INTERF_POP: pop();
break;
case INTERF_CLEAR: clear();
break;
case INTERF_FIND_LASTNAME: find_lastname();
break;
case INTERF_SAVE_STACK: save_stack_to_disk();
break;
case INTERF_LOAD_STACK: load_stack_from_disk();
break;
case INTERF_STOP:
clear();
MessageToScreen(COM_NUMB_FINISH);
return 0;
default:
printf("nieuznawany kod operacji\n");
};
}
return 0;
}
my_stack.c
#include <stdlib.h>
#include <stdio.h>
#include "my_stack.h"
#include "my_student.h"
#include "my_interface.h"
#include "string.h"
#include "error_handling.h"
#pragma warning (disable : 4996)
//// Obsluga zapisu-odczytu projektu powinna byc tu.
static FILE* pf = NULL;
static MY_STACK* first = NULL;
FreeData ptr_free_dat;
void MY_STACK_Init(FreeData pFreeDat)
{
first = NULL;
ptr_free_dat = pFreeDat;
}
void MY_STACK_Free()
{
MY_STACK *p = first, *ptmp = NULL;
while (p)
{
(*ptr_free_dat)(p->pData);
ptmp = p;
p = p->next;
free(ptmp);
}
first = NULL;
MessageToScreen(COM_NUMB_FREE_ALL);
}
MY_STACK* MY_STACK_Push(void* pdat)
{
MY_STACK* current = (MY_STACK*)malloc(sizeof(MY_STACK));
if (!current)
MessageToScreen(ERR_NUMB_ALLOC_MEM);
current->next = NULL;
if (!first)
first = current;
else
current->next = first;
first = current;
current->pData = pdat;
return current;
}
MY_STACK MY_STACK_Pop()
{
MY_STACK rv;
if (!first)
{
rv.pData = NULL;
rv.next = NULL;
}
else
{
MY_STACK* next = first->next;
rv.pData = first->pData;
rv.next = NULL;
free(first);
first = next;
}
return rv;
}
void* MY_STACK_Search(void* pSearchDat, CompData ptr_comp_fun, int FirstEntry)
{
static MY_STACK* p;
MY_STACK* ptmp = NULL;
if (FirstEntry)
p = first;
while (p)
{
if (!(*ptr_comp_fun)(p->pData, pSearchDat))
{
p = p->next;
}
else
{
ptmp = p;
p = p->next;
return ptmp->pData;
}
}
return NULL;
}
void MY_STACK_SaveToFile(const char *filename)
{
FILE* pf = fopen(filename, "wb");
if (!pf)
{
MessageToScreen(ERR_NUMB_OPEN_FILE);
}
MY_STACK* p = first;
MY_STUDENT* student; //////stos nie jest oddzielony od danych
while (p)
{
//////Stos nie powinien nic wiedziec o typie danych
student = (MY_STUDENT*)p->pData;
MY_STUDENT_SaveToFile(pf, student);
p = p->next;
}
fclose(pf);
}
void MY_STACK_LoadFromFile(const char* filename)
{
FILE* pf = fopen(filename, "rb");
if (!pf)
{
MessageToScreen(ERR_NUMB_OPEN_FILE);
return;
}
MY_STACK_Free();
MessageToScreen(COM_NUMB_READ_FILE);
MY_STUDENT_LoadFromFile(pf); //////???
fclose(pf);
}
my_stack.h
#ifndef MY_STACK___H
#define MY_STACK___H
struct MY_STACK
{
void *pData;
MY_STACK *next;
};
extern MY_STACK* first;
typedef void (*FreeData)(void* pdat);
typedef int (CompData)(void* pcurData, void *pSearchData);
void MY_STACK_Init(FreeData pFreeDat);
void MY_STACK_Free();
MY_STACK* MY_STACK_Push(void* pdat);
MY_STACK MY_STACK_Pop();
void* MY_STACK_Search(void* pSearchDat, CompData ptr_comp_fun, int FirstEntry);
void MY_STACK_SaveToFile(const char* filename);
void MY_STACK_LoadFromFile(const char* filename);
#endif
my_student.c
#include <stdio.h>
#include <stdlib.h>
#include "my_student.h"
#include "my_interface.h"
#include "string.h"
#include "my_stack.h"
#include "error_handling.h"
// Obsluga IO powinna byc tu.
void* MY_STUDENT_Init(const char* llastname, int birthyear, enum StudyDirection studydirection)
{
MY_STUDENT* pstudent = (MY_STUDENT*)malloc(sizeof(MY_STUDENT));
if (!pstudent)
MessageToScreen(ERR_NUMB_ALLOC_MEM);
if (pstudent)
{
pstudent->lastname = (char*)malloc((strlen(llastname) + 1) * sizeof(char));
if (!pstudent->lastname)
MessageToScreen(ERR_NUMB_ALLOC_MEM);
if (pstudent->lastname)
{
strcpy(pstudent->lastname, llastname);
pstudent->length = strlen(llastname);
pstudent->lastname[strlen(llastname)] = '\0';
pstudent->birth_year = birthyear;
pstudent->study_direction = studydirection;
}
else
{
free(pstudent);
pstudent = NULL;
}
}
return (void*)(pstudent);
}
void MY_STUDENT_Free(void* ptr)
{
MY_STUDENT* pStudent = (MY_STUDENT*)ptr;
if (pStudent)
{
if (pStudent->lastname)
free(pStudent->lastname);
free(pStudent);
}
}
void* MY_STUDENT_Push(const char* llastname, int birthyear, enum StudyDirection studydirection)
{
return MY_STUDENT_Init(llastname, birthyear, studydirection);
}
void MY_STUDENT_Print(void* ptr)
{
MY_STUDENT* p = (MY_STUDENT*)ptr;
if (p)
{
printf("Nazwisko : %s\n", p->lastname);
printf("Rok urodzenia: %d\n", p->birth_year);
printf("Kierunek : %d\n", p->study_direction);
}
}
int MY_STUDENT_SearchLastName(void* pCurData, void* pSearchStudent)
{
MY_STUDENT* pcur = (MY_STUDENT*)pCurData;
MY_STUDENT* psearch = (MY_STUDENT*)pSearchStudent;
if (strcmp(pcur->lastname, psearch->lastname) == 0)
return 1;
return 0;
}
void MY_STUDENT_SaveToFile(FILE *pf, void *student)
{
if (!pf)
{
MessageToScreen(ERR_NUMB_OPEN_FILE);
}
MY_STUDENT* s = (MY_STUDENT*)student;
fwrite(s, sizeof(MY_STUDENT), 1, pf);
fwrite(s->lastname, sizeof(char), s->length, pf);
}
void MY_STUDENT_LoadFromFile(FILE* pf)
{
MY_STUDENT student;
size_t count_read = 1;
count_read = fread(&student, sizeof(MY_STUDENT), 1, pf);
if (count_read != 1)
return;
int length = student.length;
student.lastname = (char*)malloc((length + 1) * sizeof(char));
if (!student.lastname)
MessageToScreen(ERR_NUMB_ALLOC_MEM);
fread(student.lastname, sizeof(char), student.length, pf);
student.lastname[student.length] = '\0';
MY_STUDENT_LoadFromFile(pf);
void* pdat = MY_STUDENT_Push(student.lastname, student.birth_year, student.study_direction);
if (!MY_STACK_Push(pdat))
printf("push error\n");
free(student.lastname);
}
my_student.h
#ifndef MY_STUDENT_H
#define MY_STUDENT_H
enum StudyDirection {
ELECTRICAL_ENGINEERING,
MECHANICAL_ENGINEERING,
COMPUTER_SCIENCE,
TOTAL_STUDY_DIRECTIONS
};
struct MY_STUDENT
{
char *lastname;
int length;
int birth_year;
enum StudyDirection study_direction;
};
void* MY_STUDENT_Init(const char* llastname, int birthyear, enum StudyDirection studydirection);
void MY_STUDENT_Free(void *ptr);
void* MY_STUDENT_Push(const char* llastname, int birthyear, enum StudyDirection studydirection);
void MY_STUDENT_Print(void* ptr);
int MY_STUDENT_SearchLastName(void* pCureData, void* pSearchStudent);
void MY_STUDENT_SaveToFile(FILE* pf, void* student);
void MY_STUDENT_LoadFromFile(FILE* pf);
#endif
my_interface.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "my_interface.h"
#include "my_student.h"
#include "my_stack.h"
#include "error_handling.h"
static const char* strtab[] =
{
"0 - push",
"1 - pop",
"2 - clear",
"3 - find lastname",
"4 - save stack to disk",
"5 - load stack from disk",
"6 - finish"
};
static const char* studytab[] =
{
"ELECTRICAL_ENGINEERING",
"MECHANICAL_ENGINEERING",
"COMPUTER_SCIENCE",
};
void menu()
{
size_t it;
for (it = 0; it < INTERF_TOT; it++)
{
printf("%s\n", strtab[it]);
}
}
void print_study_directions()
{
printf("\nDostepne kierunki studiow:\n");
for (int i = 0; i < TOTAL_STUDY_DIRECTIONS; i++)
{
printf("%d - %s\n", i, studytab[i]);
}
printf("\nWybierz number kierunku studiow: ");
}
void push()
{
char lastname[512];
int birth_year;
enum StudyDirection study_direction;
printf("Nazwisko, Rok urodzenia\n");
scanf_s("%511s", lastname, (unsigned int)sizeof(lastname));
scanf_s("%d", &birth_year);
print_study_directions();
scanf_s("%d", &study_direction);
void* pdat = MY_STUDENT_Push(lastname, birth_year, study_direction);
if (!MY_STACK_Push(pdat))
printf("push error\n");
}
void pop()
{
MY_STACK tmp = MY_STACK_Pop();
MY_STUDENT_Print(tmp.pData);
MY_STUDENT_Free(tmp.pData);
}
void find_lastname()
{
char str[128];
printf("input lastname\n");
scanf_s("%s", str, (unsigned int)sizeof(str));
MY_STUDENT searchDat;
memset(&searchDat, 0, sizeof(MY_STUDENT));
searchDat.lastname = (char*)malloc((strlen(str) + 1) * sizeof(char));
if (!searchDat.lastname)
MessageToScreen(ERR_NUMB_ALLOC_MEM);
if (searchDat.lastname != NULL)
{
strcpy(searchDat.lastname, str);
void* pDat = MY_STACK_Search(&searchDat, MY_STUDENT_SearchLastName, 1);
if (pDat)
{
printf("found : \n");
MY_STUDENT_Print(pDat);
}
while (pDat)
{
pDat = MY_STACK_Search(&searchDat, MY_STUDENT_SearchLastName, 0);
if (pDat)
{
printf("found : \n");
MY_STUDENT_Print(pDat);
}
}
}
free(searchDat.lastname);
}
void save_stack_to_disk()
{
char filename[128];
printf("input filename\n");
scanf_s("%s", filename, (unsigned int)sizeof(filename));
MY_STACK_SaveToFile(filename);
}
void load_stack_from_disk()
{
char filename[128];
printf("input filename\n");
scanf_s("%s", filename, (unsigned int)sizeof(filename));
MY_STACK_LoadFromFile(filename);
}
void clear()
{
MY_STACK_Free();
}