Списки, заполнение списков из бинарного файла - 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);
}

Объяснение кода листинга программы

  1. Объявлены следующие переменные:
    • Apteka *mas - указатель на структуру Apteka, которая представляет собой запись из списка аптек.
    • Apteka *start - указатель на первый элемент списка аптек.
    • FILE* p - указатель на файл, который будет использоваться для чтения данных из бинарного файла.
    • int i=0 - счетчик, который отслеживает количество прочитанных структур Apteka.
  2. Открывается файл apteka в бинарном режиме с помощью функции fopen(). Если файл не может быть открыт, выводится сообщение об ошибке и функция fclose() вызывается для закрытия файла.
  3. В цикле while(NahSpis) происходит очистка списка аптек путем освобождения памяти, выделенной для каждой структуры Apteka, с помощью функции free(). Значение NahSpis обновляется на значение mas, указывающее на последнюю структуру в списке.
  4. В цикле while(!feof(p)) происходит чтение структур Apteka из файла. Если чтение не удалось (например, достигли конца файла), цикл прерывается.
  5. Для каждой прочитанной структуры Apteka выделяется память с помощью функции malloc(). Если память не может быть выделена, выводится сообщение об ошибке и программа возвращается.
  6. Если это первая структура в списке, она связывается с указателем NahSpis, а указатель start указывает на NahSpis. Если это не первая структура, она связывается с next -м указателем текущей структуры в списке.
  7. В конце функции список аптек закрывается путем установки next -го указателя последней структуры в списке на NULL.
  8. Файл закрывается с помощью функции fclose().
  9. Возвращается указатель на начало списка аптек start.
  10. В конце списка устанавливается next -й указатель последней структуры в списке на NULL.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4.286 из 5
Похожие ответы