Lista jednokierunkowa - nie działające usuwanie listy

0

Witam,
Czy ktoś jest w stanie mnie nakierować co zmienić w funkcji usuwającej osobę po identyfikatorze, tak aby działała?
Za wszystkie uwagi dziekuję z góry.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define R 50

typedef struct osoba
{
	char imie[R];
	char nazwisko[R];
	unsigned int identyfikator;
	struct osoba* nastepny;
} osoba;  // Wezel listy - osoba
//--------------------------------------------------------------------------------------------------------------//
void dodajWezel(osoba **wskLista, osoba *nowy)
{
	nowy->nastepny = NULL; //inicjuje wskaznik na nastepny element na NULL
	if (*wskLista == NULL)
	{
		*wskLista = nowy;
	}
	else
	{
		osoba *wsk = *wskLista;

		while (wsk->nastepny != NULL)
		{
			wsk = wsk->nastepny;
		}
		wsk->nastepny = nowy; // nastawiam wsanzkik poprzedającego wezla na nowy wezel
	}
}
//-----------------------------------------------------------------------------------------------------------------//
void dodajOsobe(osoba **wskLista)
{
	char tab[R];
	osoba *nowy;
	nowy = (osoba*)malloc(sizeof(osoba)); //alokacja pmieci dla nowego wezla
	puts("\nPodaj imie: ");
	scanf("%s", nowy->imie);
	strcpy(tab, nowy->imie);
	puts("\nPodaj nazwisko: ");
	strcpy(tab, nowy->nazwisko);
	scanf("%s", nowy->nazwisko);
	puts("\nPodaj identyfikator: ");
	scanf("%d", &nowy->identyfikator);

	dodajWezel(wskLista, nowy); //wywolanie dodania wezla o podanych parametrach
}
//-----------------------------------------------------------------------------------------------------------------------//
int dlugoscListy(osoba *wskLista)
{
	int licznik = 0;
	osoba *wsk = wskLista;
	while (wsk != NULL) // wsk pomocniczy jest na poczatku listy
	{
		++licznik; //dodaje liczbe wezlow
		wsk = wsk->nastepny; //nastawiam wskaznik na nastepny w petli
	}
	return licznik;
	printf("Dlugosc listy wynosi: %d",licznik);
}
//-------------------------------------------------------------------------------------------------------------------------//
void usunOsobe(osoba **wskLista, int numer)
{
  
		if (numer < 1) //sprawdzam czy indeks nie jest ujemny 
		{
			printf("Nieprawidlowy indeks (>=0)!!");
		}
		else
		{
			osoba *poprzednik = NULL; //nastwaiam wskaznik poprzedniego wezla na NULL
        	osoba *wsk = *wskLista;
        	numer =wsk->identyfikator;
	        for (int i = 1; i < numer; i++)
		    {
		        poprzednik = wsk; 
		        wsk = wsk->nastepny; //przejscie na nastepny wskaznik
		        free(wsk);
		    }
		}
}
//--------------------------------------------------------------------------------------------------------------------//
void Wyswietl(osoba *wskLista)
{
	osoba *wsk = wskLista;
	if (wsk == NULL)
	{
		puts("\nLista jest pusta!");
	}
	else
	{
		int i = 1;
		puts("\nOto lista rekordow: \n");
		while (wsk != NULL)
		{
			printf("\nIdentyfikator: %d\t Imie: %s\t Nazwisko: %s\t\n", wsk->identyfikator, wsk->imie, wsk->nazwisko);
			wsk = wsk->nastepny;
			i++;
		}
	}
}

//--------------------------------------------------------------------------------------------------------------//
int main()
{
	osoba *wskLista = NULL; //pierwszy wezel na NULL
	int choice;
for(;;)
	{
		printf("\n--------LISTA JEDNOKIERUNKOWA-------\n");
		printf("1. Dodaj osobe do listy.\n");
		printf("2. Usun osobe o podanym indeksie.\n");
		printf("3. Pokaz dlugosc listy.\n");
		printf("4. Wyswietl cala liste.\n");
		printf("5. Wyjscie.\n");
		puts("Podaj wybor: ");
		scanf("%d", &choice);
		switch (choice)
			{
				case 1:
					printf("Dodawanie osoby.");
					dodajOsobe(&wskLista);
					break;
				case 2:
					printf("Usuwanie osoby.");
					int numer;
					printf("\nPodaj identyfikator osoby, ktora chcesz uusnac: ");
					scanf("%d", &numer);
					usunOsobe(&wskLista,numer);
					break;
				case 3:
				    printf("Wyswietlanie dlugosci listy.");
				    dlugoscListy(wskLista);
				    break;
				case 4:
					printf("Wyswietlanie dlugosci.");
					Wyswietl(wskLista);
					break;
				case 5:
					printf("Wychodzenie z programu. Do widzenia!");
					exit(1);
					break;
			}
	}
}
1

W pierwszej iteracji pętli for(;;) ustawiasz osoba *wskLista na NULL. Jeśli użytkownik wybierze jako pierwszą opcję numer 2 to wywoła się funkcja usunOsobe(NULL, <numer osoby do usunięcia);. Wewnątrz tej funkcji nigdy nie sprawdzasz czy wskaźnik podany w pierwszym argumencie jest równy NULL więc na pewno w tym przypadku wystąpi SEG FAULT, bo próbujesz uzyskać do niego dostęp.

Dodaj to sprawdzenie w funkcji usunOsobe:

if (*wskLista == NULL) {
    // info dla uzytkownika
}
1

Kamilka podziel zadanie na kroki:

  1. znajdź węzeł do usunięcia, oraz poprzednik tego węzła
  2. przepisz wsk->następny do poprzednik->nastepny
  3. usuń węzeł wsk
    I masz zrobione.

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