Wyświetlanie zawartości listy jednokierunkowej – dlaczego kod nie działa?

0

Hej! Pytanie pewnie jest banalne, ale nie rozumiem dlaczego ten kod nie działa... Mianowicie, chciałam dodać funkcję "wyswietl" do takiego programu i za bardzo nie wiem co tutaj jest nie tak :|

#include <iostream>

using namespace std;

struct lista
{
    int numer;
    lista *wsk;
};

void dodaj(lista *&start);
void wyswietl(lista *&start);

int main()
{
 lista *start;
 start = NULL;

dodaj(start);
wyswietl(lista *&start);

}

void dodaj(lista *&start)
{

        lista *wskaznik;
        wskaznik = start;
        for(int i = 0; i<10; i++)
        {
        wskaznik = new lista;

        cout << "podaj liczbe: ";
        cin >> wskaznik->numer;

        wskaznik->wsk = start;
        start=wskaznik;
        }

}

void wyswietl(lista *&start)
{
    lista *pomocniczy;
    pomocniczy = start;
    cout<<"pierwszy numer to: ";
    cin>>pomocniczy->numer;
    while (pomocniczy->wsk)
    {   pomocniczy = pomocniczy->wsk;
        cout << "nowy numer to: ";
        cin >>5
         pomocniczy->numer;
    }
}

1
dodaj(start);
wyswietl(lista *&start);

Zauważ że prototypy metod są takie same, tj:

void dodaj(lista *&start);
void wyswietl(lista *&start);

Jednak gdy wywołujesz te funkcje to nie podajesz typu zmiennej, dlatego dodaj(start) jest poprawne, ale wyswietl(lista *&start) już nie.

0

Oki, poprawiłam i wygląda to mniej więcej tak, ale wciąż w nieskończoność wyświetla mi się "podaj liczbę", a wydaje mi się, ze odpowiednio to ograniczyłam :( no i to wyświetlanie zawartości też kuleje, bo wcale nie wyświetla zawartości, tylko czeka na jakieś dane wejściowe

#include <iostream>

using namespace std;

struct lista
{
    int numer;
    lista *wsk;
};

void dodaj(lista *&start);
void wyswietl(lista *&start);

int main()
{
 lista *start;
 start = NULL;
 char instrukcja;

 cout<<"Wpisz instrukcję (d - jesli chcesz dodac element, w - jesli chcesz wyswietlic baze)\n"<<endl;
 while (cin>>instrukcja) {
    switch (instrukcja) {
case 'd':
    dodaj(start);
case 'w':
    wyswietl(start);
    }
 }
return 0;
}

void dodaj(lista *&start)
{

        lista *wskaznik;
        wskaznik = start;
        for(int i = 0; i<10; i++)
        {
        wskaznik = new lista;

        cout << "podaj liczbe: ";
        cin >> wskaznik->numer;

        wskaznik->wsk = start;
        start=wskaznik;
        }

}

void wyswietl(lista *&start)
{
    lista *pomocniczy;
    pomocniczy = start;
    cout<<"pierwszy numer to: ";
    cin>>pomocniczy->numer;
    while (pomocniczy->wsk)
    {   pomocniczy = pomocniczy->wsk;
        cout << "nowy numer to: ";
        cin >>pomocniczy->numer;
    }
}

1

Brakuje break po każdym case:

case 'd':
	dodaj(start);
	break; // Bez break wykona się kod poniżej czyli wyswietl(start)
case 'w':
	wyswietl(start);
	break;

Na tą chwilę funkcja wyswietl() nie ma nic wspólnego z wyświetlaniem danych tylko podmienia wszystkie liczby listy na te które wpiszesz.

0
atmal napisał(a):

Brakuje break po każdym case:

case 'd':
	dodaj(start);
	break; // Bez break wykona się kod poniżej czyli wyswietl(start)
case 'w':
	wyswietl(start);
	break;

Na tą chwilę funkcja wyswietl() nie ma nic wspólnego z wyświetlaniem danych tylko podmienia wszystkie liczby listy na te które wpiszesz.

dzięki! Poprawiłam to i jeszcze kilka innych rzeczy i na chwilę obecną ten kod jest w miarę sensowny, można dopisywać studenta do bazy i wyświetlać bazę, ale kiedy próbuję go usunąć to pojawiają się jakieś dziwne krzaczki :( googluję i googluję i jeszcze nic nie znalazłam...

#include <iostream>
#include <cstring>
using namespace std;

struct lista
{   char Imie[12];
    char Nazwisko[12];
    char numer_indeksu[7];
    lista *wsk;
};

void dodaj(lista *&start);
void wyswietl(lista *&start);
void usun(lista *&start);

int main()
{
 lista *start;
 start = NULL;
 char instrukcja;

 cout<<"Wpisz instrukcje: \n d - jesli chcesz dodac element, \n w - jesli chcesz wyswietlic baze, \n u - jesli chcesz usunac studenta z bazy\n"<<endl;
 while (cin>>instrukcja) {
    switch (instrukcja) {
case 'd':
    dodaj(start);
    break;
case 'w':
    wyswietl(start);
    break;
case 'u':
    usun(start);
    break;
    }
 }
return 0;
}

void usun(lista *&start)
{
    lista *pom;
    lista *pom1;
    pom = start;
    char indeks[7];
    pom = start;
    cout << "podaj numer indeksu studenta, ktorego chcesz usunac z bazy:\n";
    cin>>indeks;
    while (strcmp(pom->numer_indeksu,indeks)!=0) {
        pom = pom->wsk;
    }
    pom1 = pom;
    pom = pom->wsk;
    delete pom1;
}

void dodaj(lista *&start)
{

        lista *wskaznik;
        wskaznik = start;
        wskaznik = new lista;

        cout << "podaj numer indeksu: ";
        cin >> wskaznik->numer_indeksu;
        cout << "podaj imie: ";
        cin >> wskaznik->Imie;
        cout << "podaj nazwisko: ";
        cin >> wskaznik->Nazwisko;
        wskaznik->wsk = start;
        start=wskaznik;
}

void wyswietl(lista *&start)
{
    lista *pomocniczy;
    pomocniczy = start;
    cout<<pomocniczy->numer_indeksu<<" "<<pomocniczy->Imie<<" "<<pomocniczy->Nazwisko<<endl;
    while (pomocniczy->wsk)
    {   pomocniczy = pomocniczy->wsk;
        cout<<pomocniczy->numer_indeksu<<" "<<pomocniczy->Imie<<" "<<pomocniczy->Nazwisko<<endl;
    }
}

1

Źle ustawiasz wskaźnik do następnego elementu i przerywasz listę. Próbowałem przerobić to co napisałaś ale stwierdziłem że łatwiej będzie to od nowa napisać:

void usun(lista *&start)
{
	lista *pom = start;
	char indeks[7];
	cout << "podaj numer indeksu studenta, ktorego chcesz usunac z bazy:\n";
	cin >> indeks;

	// Sprawdź czy nie jest to pierwszy student:
	if (strcmp(pom->numer_indeksu, indeks) == 0)
	{
		start = start->wsk; // Przesuń start listy
		delete pom; // Usuń element
		return; // Wyjdź z funkcji
	}

	while (pom->wsk)
	{
		// Sprawdź czy następny student to ten którego szukamy
		if (strcmp(pom->wsk->numer_indeksu, indeks) == 0)
		{
			lista *temp = pom->wsk; // Element do usunięcia
			pom->wsk = temp->wsk; // Zachowaj ciągłość listy
			delete temp; // Usuń element
			break; // Wyjdź z pętli
		}
		
		pom = pom->wsk;
	}
}

Usuwanie w while działa na tej zasadzie że pom wskazuje na poprzedni element, dla przykładu: załóżmy że mamy listę jak poniżej i chcemy usunąć element b:
a -> b -> c
gdybyśmy sprawdzali czy obecny element to b to nie mielibyśmy możliwości ustawienia wskaźnika następnego elementu dla a, właśnie dlatego zamiast pom->numer_indeksu używam pom->wsk->numer_indeksu. Dzięki temu, wracając do przykładu, jestem na elemencie a, wiem że następny jest do usunięcia, zapisuję go więc do zmiennej temp a jako następny element po a ustawiam temp->wsk czyli c.
To co napisałem wyżej działa jeżeli do usunięcia nie jest pierwszy element z listy, dlatego dodałem przed while krótkiego if.

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