Lista dwukierunkowa w C

0

Witam, napisałem listę jednokierunkową w C. Zacząłem przerabiać kod na listę dwukierunkową. Pierwszym krokiem było dodanie wskaźnika PREV w stukturze. Po czym ustawiam ten wskaźnik przy dodawaniu każdego nowego elementu do listy. Niestety muszę coś źle robić. Za każdym razem gdy próbuje się odwołać do byle którego poprzednika, program przestaje działać. Myślę, że źle ustawiam wskaźnik przy dodawaniu elementów, aczkolwiek nic nie znalazłem przez kilkugodzinne naprawianie kodu. Dzięki za pomoc :-)

 
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int i;
char mar[100];
char mod[100];
 
typedef struct Auto
{
 
       char marka[100];
       char model[100];
       int rok;
       int moc;
       struct Auto* next;
	   struct Auto* prev;
              } Auto ;
 
// Oblicza dlugosc listy
int dlugosc_listy(Auto* lista)
{
    int d = 0;
    Auto* wsk = lista;
    while(wsk != NULL)
    {
              d++;
              wsk = wsk->next;
              }
    return d;
    }
 
// Dodaje nowy wezel do listy
void dodaj(Auto** lista, Auto* nowy)
{
     nowy->next=NULL;
	 

     if((*lista)==NULL)
     {
      *lista = nowy;
	  nowy->prev=NULL;
     }
     else
     {
		 Auto* wsk = *lista;
         while(wsk->next != NULL)
         {
         wsk = wsk->next;
 
         }
		 wsk->prev= wsk;
         wsk->next = nowy; 
         }
     }              
 
// Dodaje Samochód do listy              
void dodajautko(Auto** lista)
{    
     Auto* nowy = (Auto*)malloc(sizeof(Auto));
     printf("Podaj Marke: ");
     scanf("%s", nowy->marka);
 
     printf("Podaj Model: ");
     scanf("%s", nowy->model);
 
     printf("Podaj rok produkcji: " );
     scanf("%d", &(nowy->rok));
 
	 printf("Podaj moc: " );
     scanf("%d", &(nowy->moc));
   
 
     dodaj(lista, nowy);     
}
 
//Wypisuje cala liste
void wypisz_liste(Auto* lista)
{	int i=1;
 
     Auto* wsk = lista;
	// Auto* wsk2 = lista;
	 //*wsk2=*(wsk2+(dlugosc_listy(lista)-1));

    if(lista == NULL)
    printf("LISTA JEST PUSTA");
    else
	{printf("Lista zawiera %d elementow: \n", dlugosc_listy(lista) );}

     while(wsk != NULL)
     {
            printf("%d %s %s %d %d\n", i, wsk->marka, wsk->model, wsk->rok, wsk->moc);
            wsk=wsk->next;
            i++;

			
     }    // wsk=wsk->prev;
			//printf("%d %s %s %d %d\n", i, wsk->marka, wsk->model, wsk->rok, wsk->moc);
       
           
}
 

void zapisz_liste(Auto* lista)
{	int i=1;
	Auto* wsk = lista;
	char nazwa[100];
	FILE *plik2;

	printf("Podaj nazwe pliku:\n");
	scanf("%s",nazwa);

	plik2 = fopen(nazwa,"w");
	if(plik2==NULL) printf("Nie mozna otworzyc pliku\n");
	
     
 
    if(lista == NULL)
    fprintf(plik2, "LISTA JEST PUSTA");
    
     while(wsk != NULL)
     {
            fprintf(plik2, "%d %s %s %d %d\n", i, wsk->marka, wsk->model, wsk->rok, wsk->moc);
            wsk=wsk->next;
            i++;
     }

	fclose(plik2);
	//system(nazwa);
	printf("Zapisane!\n");
}

//Usuwa element z listy
void usun(Auto** lista, int ID)
{
             Auto* poprzedni = NULL;
             Auto* 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);
             }
			  printf("Samochod zostal usuniety!\n");
}
 
// Usuwa samochód po indexie
void usun_autko(Auto** lista)
{
     int ID;
     printf("Podaj indeks samochodu: " );
     scanf("%d", &ID);
 
     if((ID > dlugosc_listy(*lista)) || (ID < 1))
     {
           printf("Nie ma takiego indeksu");
 
     }
     else
     {
         usun(lista,ID);         
     }
}
     int usun_marmod_lista(char* mar, char* mod, Auto** lista)
     {
          Auto* poprzedni=NULL;
          Auto* wsk= *lista;
 
          while((wsk != NULL) && ( ( strcmp(wsk->marka, mar)!=0) || (strcmp(wsk->model, mod )!=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);
                 }
			   printf("Samochod zostal usuniety!\n");
               return 1;
               }
     }
 
//Usuwa auto po marce i modelu
     void usun_marmod(Auto** lista)
     {
          char mar[100];
          char mod[100];
 
           printf("\nPodaj marke: ");
     scanf("%s", mar);
 
     printf("Podaj model: ");
     scanf("%s", mod);
 
          if(!usun_marmod_lista(mar, mod, lista))
          printf("Auto nie zostalo usuniete, nie ma takiego samochodu\n");
 
      }
 
         void wypisz_autko_lista(Auto* lista, int ID)
          {
              int i;
              Auto* wsk = lista;
          for(i = 1; i < ID; i++)
             {
                     wsk=wsk->next;
 
                     }
             printf("%d %s %s %d %c\n", i, wsk->marka, wsk->model, wsk->rok, wsk->moc);     
                                    }
 
          //wypisz autko o podanym indexie
          void wypisz_autko(Auto* lista)
          {
               int ID;
 
               printf("Podaj numer osoby: " );
               scanf("%d", &ID);
 
               if((ID > dlugosc_listy(lista)) || (ID < 1))
                 {
           printf("Nie ma takiego indeksu");
 
           }
           else
           wypisz_autko_lista(lista, ID);    
 
               }
 
int main()
{
    Auto* lista = NULL;
 
              int option=1;
 
 while(option != 0)
       {
printf("\n\n MENU");
printf("\n\n\n 0 Wyjscie z programu");
printf("\n 1 Wpisz dane samochodu do bazy");
printf("\n 2 Usun auto o podanym indeksie");
printf("\n 3 Usun auto o podanej marce i modelu");
printf("\n 4 Wyswietl samochod o podanym indeksie");
printf("\n 5 Wyswietl cala liste\n");
 
           scanf("%d", &option);
 
           switch(option)
           {             
 
                         case 1: 
                              printf("DODAWANIE SAMOCHODU\n");
                              dodajautko(&lista);
                              break;
 
                         case 2: 
                              printf("USUWANIE SAMOCHODU O PODANYM INDEKSIE\n");
                              usun_autko(&lista);
                              break;
 
                        case 3: 
                              printf("USUWANIE SAMOCHODU NA BAZIE MARKI I MODELU");
							  usun_marmod(&lista);
							  break;
 
                         case 4: 
                              printf("WYSWIETL SAMOCHOD O PODANYM INDEKSIE\n");
                              wypisz_autko(lista);
                              break;
 
                         case 5: 
                              printf("WYSWIETL CALA BAZE\n");
                              wypisz_liste(lista);
                              break;
						 case 6:
							  zapisz_liste(lista);
							  break;
          }				
      }
return 0;
    }
2
  1. Zapoznaj się z pojęciem formatowania kodu
  2. Nie nadużywaj postinkrementacji: for(i = 1; i < ID; ++i) zadziała tak samo dobrze.
  3. Powinieneś to wszystko wywalić i napisać od nowa, poczynając od deklaracji struktury.
  4. jest: wsk->prev= wsk; ma być: nowy->prev= wsk;
0

Dziękuję, zastosuję się do wskazówek. Niestety po zmianie wskaźnika

 wsk->prev= wsk;  

na nowy->prev= wsk;

 Program działa tak samo. W żadnym momencie nie mogę wypisać poprzedniego elementu, program przestaje działać.
2

ten kod jest nieczytelny
zmienne globalne
masz zadeklarowane i globalnie i lokalnie i zapewne nawet nie masz pojecia ktorego uzywasz

Wez debugger do reki i sprawdzaj gdzie sie wywala. Jak nie to debugguj recznie w sensie

  1. otworz plik do zapisu
  2. po kazdej wiekszej fukncji zapisz do pliku "wykonala sie funkcja TAKAaTAKA"

jezeli program sie wywali zobacz ktore funkcja zostala wyspisana ostatnia
sprawdzaj w tamtej funkcji gdzie sie cos wywali
bedziesz znac linijke gdzie sie wywalilo

jezeli nie bedziesz wiedziec co z nia nie tak to wklej ja tutaj

0

W ogóle dlaczego przy dodawaniu nowego elementu ciągle przewijasz listę na koniec? Najlepiej dodawać po prostu na początek i zastępować roota nowym elementem, albo mieć gdzieś wskaźnik do ostatniego elementu, żeby nie przewijać bez sensu miliona elementów listy - jeżeli już upierasz się przy dodawaniu na koniec.

0
cinek151511 napisał(a):

Dziękuję, zastosuję się do wskazówek. Niestety po zmianie wskaźnika

 wsk->prev= wsk;  

na nowy->prev= wsk;

 Program działa tak samo. W żadnym momencie nie mogę wypisać poprzedniego elementu, program przestaje działać.
 Chrzani Waść: http://ideone.com/58wopU
0

Mój błąd polegał na tym, że próbowałem ze wskaźnika przejść na poprzedni wskaźnik, gdy aktualny był NULLem.
Dziękuję za pomoc :-)

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