Списки, заполнение списков из бинарного файла - C (СИ)
Формулировка задачи:
Нужно из бинарного файла восстановить список (
функция res()
). Помогите разобраться почему восстанавливает только последнею запись# include <stdio.h> # include <iostream.h> # include <conio.h> # include <string.h> int menu(int kp,char *nazv[]); void main(); void sozd(); void dobav(); void dobav_ponom(); void prosm(); void ydal(); void osn1(); void osn2(); void osn3(); void bekap(); void res(); struct Apteka { char nazv_lek[30]; char proizv[30]; long int cena; char vid_lek[20]; char prim[50]; char otpusk[20]; struct Apteka *next; } ; struct Apteka *NahSpis=NULL; void main() { int kp=11, nom; char *nazv[]={"Sozdanie","Dobavlenie","Dobavit po nimery", "Prosmotr","Ydalit po nimery","Udalit vse svedenija o lekarstvah nahodjashhihsja v svobodnoj prodazhe", "Uvelichit cenu dlja zadannogo lekarstva na zadannuju velichinu ", "Vyvesti vse svedenija o lekarstvah zadannogo vida", "Kopir. zapisi v file","Vostonovlenie iz file","Vixod"}; while(1) { clrscr(); nom=menu(kp,nazv); switch(nom) { case 1:sozd();break; case 2:dobav(); break; case 3:dobav_ponom(); break; case 4:prosm();break; case 5:ydal();break; case 6:osn1();break; case 7:osn2();break; case 8:osn3();break; case 9:bekap();break; case 10:res();break; case 11:return; }}} int menu(int kp,char *nazv[]) { int i,nomer; for (i=0;i<kp;i++) printf("%d.%s\n",i+1,nazv[i]); printf("\n\n Vyberi punkt menju->"); scanf("%d",&nomer); return nomer; } void sozd() { Apteka *mas=new Apteka, *t; clrscr(); for(;;) { clrscr(); mas = new Apteka; printf("Vvedite nazvanie lekarstva, * dlja vyhoda -> "); flushall(); gets(mas->nazv_lek); if(mas->nazv_lek[0]=='*') return; printf("\n Vvedite proizvoditelja-> "); flushall(); gets(mas->proizv); printf("\n Vvedite cenu-> "); flushall(); scanf("%ld",&mas->cena); printf("\n Vvedite vid lekarstva-> "); flushall(); gets(mas->vid_lek); printf("\n Vvedite pokazanija k primeneniju s dozirovkami -> "); fflush (stdin); gets(mas->prim); printf("\n Vvedite sposob otpuska-> "); flushall(); gets(mas->otpusk); if (NahSpis==0) {NahSpis=mas;} else { t=NahSpis; while (t->next!=0) t=t->next; t->next=mas; } mas->next=NULL; } mas=NULL; } void dobav_ponom() { int nom,kol=0; printf("\nVvedi nomer elementa dla vstavki-> "); scanf("%d",&nom); Apteka *t; t=NahSpis; while (t!=0) { kol++; t=t->next; } if (nom>kol) printf("\nNet elem s takim nomerom"); else { t=NahSpis; for(int i=0; i<nom-1;i++) { t=t->next; } Apteka *mas=new Apteka; printf("Vvedite nazvanie lekarstva -> "); flushall(); gets(mas->nazv_lek); printf("\n Vvedite proizvoditelja-> "); flushall(); gets(mas->proizv); printf("\n Vvedite cenu-> "); flushall(); scanf("%ld",&mas->cena); printf("\n Vvedite vid lekarstva-> "); flushall(); gets(mas->vid_lek); printf("\n Vvedite pokazanija k primeneniju s dozirovkami -> "); fflush (stdin); gets(mas->prim); printf("\n Vvedite sposob otpuska-> "); flushall(); gets(mas->otpusk); if(nom==0) { mas->next=NahSpis; NahSpis=mas;} else { mas->next=t->next; t->next=mas; } } getch(); } void dobav() { Apteka *mas=new Apteka, *t; clrscr(); printf("Vvedite nazvanie lekarstva -> "); flushall(); gets(mas->nazv_lek); printf("\n Vvedite proizvoditelja-> "); flushall(); gets(mas->proizv); printf("\n Vvedite cenu-> "); flushall(); scanf("%ld",&mas->cena); printf("\n Vvedite vid lekarstva-> "); flushall(); gets(mas->vid_lek); printf("\n Vvedite pokazanija k primeneniju s dozirovkami -> "); fflush (stdin); gets(mas->prim); printf("\n Vvedite sposob otpuska-> "); flushall(); gets(mas->otpusk); if (NahSpis==0) {NahSpis=mas;} else { t=NahSpis; while (t->next!=0) t=t->next; t->next=mas; } mas->next=0; } void prosm() { int i; Apteka *mas; printf("\n-------------------------------------------------------------------------------"); printf("\n| Nazvanie | Proizvoditel | Cena | Vid | Pokazanija | Sposob |"); printf("\n| lekarstva | | | lekarstva | k primeneniju | otpuska |"); printf("\n-------------------------------------------------------------------------------"); mas=NahSpis; while(mas!=0) { printf("\n|%11s | %12s |%8ld| %9s |%16s| %9s |",mas->nazv_lek,mas->proizv,mas->cena,mas->vid_lek,mas->prim,mas->otpusk); mas=mas->next; } printf("\n-------------------------------------------------------------------------------"); getch(); } void ydal() { int nom,i,kol; clrscr(); printf("\n Vvedite nomer udaljaemoj zapisi->"); scanf("%d",&nom); struct Apteka *t,*elem; t=NahSpis; while (t!=0) { kol++; t=t->next; } if (nom>kol) printf("\n Zapisi s takim nomerom net"); else { t=NahSpis; for(int i=0; i<nom-1;i++) { t=t->next; } if(nom==1) { NahSpis=t->next;} else { elem=NahSpis; while(elem->next!=t)elem=elem->next; elem->next=t->next; delete t; } } getch(); } void osn1() { clrscr(); struct Apteka *mas1=NahSpis,*mas2=NahSpis; if (strcmp(mas1->otpusk,"sv pr")==0) NahSpis= mas1-> next; while(mas1!=NULL) { if(mas2->next!=NULL) { mas2 = mas2->next; if(strcmp(mas2->otpusk,"sv pr")==0) { mas1->next = mas2->next; } } mas1 = mas1->next; } } void osn2() { Apteka *mas1= NahSpis; char zak[20]; int stoim; clrscr(); printf("\n Vvedite nazvanie lekarstva -> "); scanf("%s",zak); while(mas1!=NULL) { if(!strcmp(mas1->nazv_lek, zak)) { printf("\n Vvedite na skolko uvelichit cenu lekarstvo \n"); flushall(); scanf("%ld",&stoim); mas1->cena+=stoim; } mas1 = mas1->next; } } void osn3() { struct Apteka *mas; char vid[20]; int i; clrscr(); printf("\n Vvedite vid lekarstva->"); flushall(); gets(vid); mas=NahSpis; int pr=-1; printf("\n-------------------------------------------------------------------------------"); printf("\n| Nazvanie | Proizvoditel | Cena | Vid | Pokazanija | Sposob |"); printf("\n| lekarstva | | | lekarstva | k primeneniju | otpuska |"); printf("\n-------------------------------------------------------------------------------"); while(mas->next!=NULL) { if(strcmp(mas->vid_lek,vid)==0) { pr=1; printf("\n|%11s | %12s |%8ld| %9s |%16s| %9s |",mas->nazv_lek,mas->proizv,mas->cena,mas->vid_lek,mas->prim,mas->otpusk); } mas=mas->next; } if(strcmp(mas->vid_lek,vid)==0) { pr=1; printf("\n|%11s | %12s |%8ld| %9s |%16s| %9s |",mas->nazv_lek,mas->proizv,mas->cena,mas->vid_lek,mas->prim,mas->otpusk); } if(pr==-1) printf("\n Net zapisej s takim vidom lekarstv"); getch(); } void bekap() { Apteka *mas= NahSpis; FILE *f; f = fopen("apteka", "wb"); while(mas) { fwrite(mas, sizeof(*mas), 1, f); mas = mas->next; } fcloseall(); } void res() { Apteka *mas; FILE* p ; p = fopen("apteka", "rb"); if(!p) {printf("Невозможно открыть файл.\n"); return; } while(NahSpis) { mas = NahSpis->next; free(mas); NahSpis = mas; } while(!feof(p)) { mas = (struct Apteka *) malloc(sizeof(struct Apteka)); if(!mas ) { printf("Нет свободной памяти"); return;} if(1 != fread(mas, sizeof(struct Apteka), 1, p)) break; NahSpis=mas; mas=mas->next; } mas->next=0; fclose(p); }
Решение задачи: «Списки, заполнение списков из бинарного файла»
textual
Листинг программы
void res() { Apteka *mas,*start; FILE* p ; int i=0; p = fopen("apteka", "rb"); if(!p) {printf("Невозможно открыть файл.\n"); return; } while(NahSpis) { mas = NahSpis->next; free(mas); NahSpis = mas; } while(!feof(p)) { mas = (struct Apteka *) malloc(sizeof(struct Apteka)); if(!mas ) { printf("Нет свободной памяти"); return;} if(1 != fread(mas, sizeof(struct Apteka), 1, p)) break; if(i==0){NahSpis=mas;start= NahSpis;i++;} else{ NahSpis->next=mas; NahSpis= NahSpis->next;} } NahSpis=start; mas->next=0; fclose(p); }
Объяснение кода листинга программы
- Объявлены следующие переменные:
Apteka *mas
- указатель на структуруApteka
, которая представляет собой запись из списка аптек.Apteka *start
- указатель на первый элемент списка аптек.FILE* p
- указатель на файл, который будет использоваться для чтения данных из бинарного файла.int i=0
- счетчик, который отслеживает количество прочитанных структурApteka
.
- Открывается файл
apteka
в бинарном режиме с помощью функцииfopen()
. Если файл не может быть открыт, выводится сообщение об ошибке и функцияfclose()
вызывается для закрытия файла. - В цикле while(NahSpis) происходит очистка списка аптек путем освобождения памяти, выделенной для каждой структуры
Apteka
, с помощью функцииfree()
. ЗначениеNahSpis
обновляется на значениеmas
, указывающее на последнюю структуру в списке. - В цикле while(!feof(p)) происходит чтение структур
Apteka
из файла. Если чтение не удалось (например, достигли конца файла), цикл прерывается. - Для каждой прочитанной структуры
Apteka
выделяется память с помощью функцииmalloc()
. Если память не может быть выделена, выводится сообщение об ошибке и программа возвращается. - Если это первая структура в списке, она связывается с указателем
NahSpis
, а указательstart
указывает наNahSpis
. Если это не первая структура, она связывается сnext
-м указателем текущей структуры в списке. - В конце функции список аптек закрывается путем установки
next
-го указателя последней структуры в списке наNULL
. - Файл закрывается с помощью функции
fclose()
. - Возвращается указатель на начало списка аптек
start
. - В конце списка устанавливается
next
-й указатель последней структуры в списке наNULL
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д