Lista jednokierunkowa [C]

0

Cześć wszystkim. Muszę zrobić bazę danych osób w czystym C. Coś tam naskrobałem, ale przy wpisywaniu 3 osoby program się wysypuje. Siedzę nad tym już parę godzin i już mi się pomysły kończą co może być źle. Z góry dzięki za pomoc.

#include <stdio.h>
#include <string.h>


typedef struct Osoba
{
    
       char imie[100];
       char nazwisko[100];
       int wiek;
       char plec;
       struct Osoba* next;
              } Osoba ;

// zlicza dlugosc listy
int dlugosc_listy(Osoba* lista)
{
    int d = 0;
    Osoba* wsk = lista;
    while(wsk != NULL)
    {
              d++;
              wsk = wsk->next;
              }
    return d;
    }

// dodaje nowy wezel do listy
void dodaj(Osoba** lista, Osoba* nowa)
{
     nowa->next=NULL;
     
     if((*lista)==NULL)
     {
      *lista = nowa;
                     }
     else
     {
         Osoba* wsk = *lista;
         while((*lista)->next != NULL)
         {
         wsk = wsk->next;
         
         }
         wsk->next = nowa;
         
         }
     }              

// dodaje osobe do listy              
void dodajOsobe(Osoba** lista)
{    char line[500];
     Osoba* nowa = (Osoba*)malloc(sizeof(Osoba));
     printf("Podaj imie: ");
     scanf("%s", nowa->imie);
     
     printf("Podaj nazwisko: ");
     scanf("%s", nowa->nazwisko);
     
     printf("Podaj wiek: " );
     scanf("%d", &(nowa->wiek));
     
     printf("Podaj plec: " );
     gets(line);
     gets(line);
     nowa->plec=line[0];

     dodaj(lista, nowa);     
}

//Wypisuje cala liste
void wypisz_liste(Osoba* lista)
{
 
     Osoba* wsk = lista;
 
     if(lista == NULL)
     printf("LISTA JEST PUSTA");
     else
     printf("Lista zawiera %d elementow: \n", dlugosc_listy(lista) );
     int i = 1;
     while( wsk != NULL)
     {
            printf("%d %s %s %d %c\n", i, wsk->imie, wsk->nazwisko, wsk->wiek, wsk->plec);
            wsk=wsk->next;
            i++;
     }
}

//Usuwa element z listy
void usun(Osoba** lista, int ID)
{
             Osoba* poprzedni = NULL;
             Osoba* wsk = *lista;
             int i;            
             for(i = 1; i < ID; i++)
             {
                     poprzedni=wsk;
                     wsk=wsk->next;
                     
                     }
             if(poprzedni==NULL)
             {
             (*lista)=(*lista)->next;
             free(wsk);                               
             }
             else
             {
                 poprzedni->next=wsk->next;
                 free(wsk);
                 }
}

// Usuwa osobe po indexie
void usun_osobe(Osoba** lista)
{
     int ID;
     printf("Podaj indeks osoby: " );
     scanf("%d", &ID);
     
     if((ID > dlugosc_listy(*lista)) || (ID < 1))
     {
           printf("Nie ma takiego indeksu");
           
           }
     else
     {
         usun(lista,ID);         
         }
     }
     int usun_imnaz_lista(char* im, char* naz, Osoba** lista)
     {
          Osoba* poprzedni=NULL;
          Osoba* wsk= *lista;

          while((wsk != NULL) && ( ( strcmp(wsk->imie, im)!=0) || (strcmp(wsk->nazwisko, naz )!=0) ))
          {
                     poprzedni=wsk;
                     wsk=wsk->next;
          }
          if(wsk == NULL )
          {
                 return 0;
                 }
          else 
          {
                if(poprzedni==NULL)
             {
             (*lista)=(*lista)->next;
             free(wsk);                               
             }
             else
             {
                 poprzedni->next=wsk->next;
                 free(wsk);
                 }
               return 1;
               }
     }
     
//usuwa po imieniu i nazwisku
     void usun_imnaz(Osoba** lista)
     {
          char im[100];
          char naz[100];
          
           printf("Podaj imie: ");
     scanf("%s", im);
     
     printf("Podaj nazwisko: ");
     scanf("%s", naz);
          
          if(usun_imnaz_lista(im, naz, lista))
          
          printf("Osoba zostala usunieta");
          else
          printf("Osoba nie zostala usunieta, nie ma takiej osoby");
          
          }
          
         void wypisz_osobe_lista(Osoba* lista, int ID)
          {
              int i;
              Osoba* wsk = lista;
          for(i = 1; i < ID; i++)
             {
                     wsk=wsk->next;
                     
                     }
             printf("%d %s %s %d %c\n", i, wsk->imie, wsk->nazwisko, wsk->wiek, wsk->plec);     
                                    }
                                    
          //wypisz osobe o podanym indexie
          void wypisz_osobe(Osoba* lista)
          {
               int ID;
               
               printf("Podaj numer osoby: " );
               scanf("%d", &ID);
               
               if((ID > dlugosc_listy(lista)) || (ID < 1))
                 {
           printf("Nie ma takiego indeksu");
           
           }
           else
           wypisz_osobe_lista(lista, ID);    
               
               }
          
int main()
{
    Osoba* lista = NULL;
      
              int option;
                  
 while(option != 0)
           {
printf("\n\n MENU");
printf("\n\n\n 0 Wyjscie z programu");
printf("\n 1 Wpisz dane osoby do bazy");
printf("\n 2 Usun osobe o podanym indeksie");
printf("\n 3 Usun osobe o podanych imieniu i nazwisku");
printf("\n 4 Wyswietl osobe o podanym indeksie");
printf("\n 5 Wyswietl cala liste\n");

           scanf("%d", &option);
          
           switch(option)
           {             
                         
                         case 1: 
                              printf("DODAWANIE OSOBY\n");
                              dodajOsobe(&lista);
                              break;
                              
                         case 2: 
                              printf("USUWANIE OSOBY O PODANYM INDEKSIE\n");
                              usun_osobe(&lista);
                              break;
                              
                        case 3: 
                              printf("USUWANIE OSOBY NA BAZIE IMIENIA I NAZWISKA");
                              usun_imnaz_lista(im, naz, &lista);
                              menu();
                              
                         case 4: 
                              printf("WYSWIETL OSOBE O PODANYM INDEKSIE\n");
                              wypisz_osobe(lista);
                              break;
                              
                         case 5: 
                              printf("WYSWIETL CALA BAZE\n");
                              wypisz_liste(lista);
                              break;
                         }
          }

   int key;
   scanf("%d", &key);
    
  
    }
0

Tu jest źle:

         Osoba* wsk = *lista;
         while((*lista)->next != NULL)
         {
         wsk = wsk->next;
 
         }
         wsk->next = nowa;
 
         }

Zamiast (*lista)->next powinno być wsk->next:

         Osoba* wsk = *lista;
         while(wsk->next != NULL)
         {
         wsk = wsk->next;
 
         }
         wsk->next = nowa;
 
         }

Tak poza tym to można to prościej zrobić:

void dodaj(Osoba** lista, Osoba* nowa)
{
     while (*lista != NULL) lista = &((*lista)->next);
     *lista = nowa;
     nowa->next = NULL;
}
0

A jeszcze ładniej wygląda z użyciem referencji:

void dodaj(Osoba *&lista,Osoba* nowa)
  {
   while(lista) lista=lista->next;
   // lista=nowa;
   // nowa->next=0; // to powinno być zrobione w funkcji wywołującej.
   // ale jeżeli już to:
   (lista=nowa)->next=0;
  }

Oczywiście wywoływanie takiej funkcji też jest ładniejsze.

0

Dzięki wielkie, wszystko działa :)

0
_13th_Dragon napisał(a):
void dodaj(Osoba *&lista,Osoba* nowa)
>   {
>    while(lista) lista=lista->next;
W ten sposób zniszczysz wskaźnik głowy listy.

 > ##### [_13th_Dragon napisał(a)](http://4programmers.net/Forum/846964):
> (lista=nowa)->next=0;
Nieczytelne, lepiej rozbić na 2 linijki. No i jeśli wskaźniki to `NULL` a nie 0!

1 użytkowników online, w tym zalogowanych: 0, gości: 1