Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Dodawanie, drukowanie elementów listy jednokierunkowej

Ostatnio zmodyfikowano 2016-05-20 20:13
Autor Wiadomość
locf
Temat założony przez niniejszego użytkownika
Dodawanie, drukowanie elementów listy jednokierunkowej
» 2016-05-19 05:21:05
Witam ponownie
mam napisać program, w którym dodaję elementy listy (dane o zwierzętach np. imię, wiek, opiekun) na koniec listy, dopóki imię jest różne od "koniec". Mam wydrukować ją.
Mam dodać element listy i wstawić go na początek. Wydrukować listę, a potem usunąć listę.

Zrobiłem dotychczas coś takiego

C/C++
#include <iostream>
#include <string>
#include <cstdlib>
#include <iomanip>


using namespace std;

struct StZoo
{
    string imieZwierza;
    string gatunekZwierza;
    int wiekZwierza;
    string nazwiskoOpiekuna;
    StZoo * nast;
};

void drukujListe( StZoo *& adres )
{
    while( adres != NULL )
    {
        cout << endl;
        cout << adres->imieZwierza << " \t\t";
        cout << adres->gatunekZwierza << " \t\t";
        cout << adres->wiekZwierza << " \t\t";
        cout << adres->nazwiskoOpiekuna << " \t\t";
        cout << endl;
        adres = adres->nast;
    }
}

void usunList( StZoo *& glowa )
{
    StZoo * pom;
    while( glowa != NULL )
    {
        pom = glowa;
        glowa = glowa->nast;
        delete pom;
    }
}

int main()
{
    StZoo * glowa, * aktualny, * ogon;
    string imie;
    string gatunek;
    string opiekun;
    int wiek = 0;
    bool czyTworzeGlowe = true;
    bool czyTworzeKolejny = true;
   
    cout << "Lista z danymi zwierzat.\n" << endl;
    cout << "Wprowadz imie zwierzecia, gatunek, wiek ";
    cout << "i nazwisko opiekuna \n";
    cout << "Zwierze o imieniu 'koniec' nie bedzie ujawnione w liscie. Konczy ono wpisywanie. \n\n";
   
    cout << "Prosze podac imie zwierzecia: ";
    cin >> imie;
    if( imie == "koniec" )
    {
        //wtedy od razu konczymy wpisywanie i nie pytam o gatunek, wiek, opiekuna
        czyTworzeGlowe = false;
        cout << "Koniec tworzenia listy" << endl;
    }
    else
    {
        cout << "Prosze podac gatunek zwierzecia: ";
        cin >> gatunek;
        cout << "Prosze podac wiek zwierzecia: ";
        cin >> wiek;
        cout << "Prosze podac nazwisko opiekuna: ";
        cin >> opiekun;
        cout << endl;
    }
   
    // gdy mam wczytane imie, gatunek, wiek, opiekuna
    // operatorem new tworze nowy obiekt danych i jego adres
    // przypisuje zmiennej glowa
   
    if( czyTworzeGlowe == true )
    {
        glowa = new StZoo;
       
        glowa->imieZwierza = imie;
        glowa->gatunekZwierza = gatunek;
        glowa->wiekZwierza = wiek;
        glowa->nazwiskoOpiekuna = opiekun;
        glowa->nast = NULL;
        ogon = glowa;
    }
   
    if( czyTworzeGlowe == true )
    {
        czyTworzeKolejny = true;
    }
    else
    {
        czyTworzeKolejny = false;
    }
   
    // jesli zwierze w zmiennej glowa ma imie inne niz 'koniec'
   
    while( czyTworzeKolejny == true )
    {
        cout << "Prosze podac imie zwierzecia: ";
        cin >> imie;
        if( imie == "koniec" )
        {
            czyTworzeKolejny = false;
        }
        else
        {
            cout << "Prosze podac gatunek zwierzecia: ";
            cin >> gatunek;
            cout << "Prosze podac wiek zwierzecia: ";
            cin >> wiek;
            cout << "Prosze podac nazwisko opiekuna: ";
            cin >> opiekun;
            cout << endl;
        }
       
        if( czyTworzeKolejny == true )
        {
            aktualny = new StZoo;
            aktualny->imieZwierza = imie;
            aktualny->gatunekZwierza = gatunek;
            aktualny->wiekZwierza = wiek;
            aktualny->nazwiskoOpiekuna = opiekun;
           
            aktualny->nast = NULL;
            ogon->nast = aktualny;
            ogon = aktualny;
        }
        else
        {
            cout << "Koniec tworzenia listy";
        }
       
    }
    if( glowa->nast != NULL )
         drukujListe( glowa );
   
    // dodawanie na poczatek listy
    //***************************************************
    if( czyTworzeGlowe == true )
    {
       
        aktualny = new StZoo;
        cout << "Prosze podac imie zwierzecia: ";
        cin >> imie;
        cout << "Prosze podac gatunek zwierzecia: ";
        cin >> gatunek;
        cout << "Prosze podac wiek zwierzecia: ";
        cin >> wiek;
        cout << "Prosze podac nazwisko opiekuna: ";
        cin >> opiekun;
       
        aktualny->imieZwierza = imie;
        aktualny->gatunekZwierza = gatunek;
        aktualny->wiekZwierza = wiek;
        aktualny->nazwiskoOpiekuna = opiekun;
       
        aktualny->nast = glowa;
        glowa = aktualny;
    }
   
    if( glowa )
    {
        cout << "Lista z elementem dodanym na poczatku" << endl;
        drukujListe( glowa );
    }
   
   
    return 0;
}

Tylko wywołanie funkcji drukujListe na końcu nie drukuje całej listy, ale ostatni element dodany na początku.
Jak to poprawić? Czy ktoś mógłby mi pomóc?
P-148398
carlosmay
» 2016-05-19 08:41:40
StZoo * glowa, * aktualny, * ogon;
 
Próbujesz używać niezaincjalizowanycj wskaźników.
tutaj:
C/C++
if( glowa->nast != NULL )
     drukujListe( glowa );
i tutatj:
ogon->nast = aktualny;

Ten kod to spagetti. Podziel go na funkcje.
P-148399
darko202
» 2016-05-19 09:00:07
1.
przeczytaj np.  http://www.algorytm.org​/klasyczne/lista/lista-1-c.html
i podobnie jak tam wyodrębnij powtarzające się kawałki kodu tworząc odpowiednie funkcje

to uprości Ci kod

2.
zapoznaj się z technologią debugowania programu

https://www.google.pl/​?gws_rd=ssl#q=debugging%20c%2B%2B

pozwala ona na wykonywanie programu linia po linii i śledzenia zmian użytych zmiennych

debug dostępny jest dla wszystkich znanych kompilatorów C++
link powyżej + "używany kompilator"

3.
>> Tylko wywołanie funkcji drukujListe na końcu nie drukuje całej listy, ale ostatni element dodany na początku.

problem jest w StZoo *& adres a potem modyfikowaniu  adres = adres->nast
po opuszczeniu  adres listy wskazuje na NULL
trzeba utworzyć wskaźnik pomocniczy i jego zmieniać a nie wskaźnik całej listy
C/C++
void drukujListe( StZoo *& adres ) //
{
    while( adres != NULL )
    {
        cout << endl;
        cout << adres->imieZwierza << " \t\t";
        cout << adres->gatunekZwierza << " \t\t";
        cout << adres->wiekZwierza << " \t\t";
        cout << adres->nazwiskoOpiekuna << " \t\t";
        cout << endl;
        adres = adres->nast; zmieniasz adres
    }
}

P-148400
locf
Temat założony przez niniejszego użytkownika
» 2016-05-20 19:35:21
Dzięki za wypowiedzi. Wiem, że kod ten nie jest "najwyższych lotów". Postaram się go poprawić.
Zasadą jest, że każdy wskaźnik mogę inicjalizować NULL-em i nie wpłynie to negatywnie na działanie programu?
P-148450
carlosmay
» 2016-05-20 20:13:42
Zasadą jest, że każdy wskaźnik mogę inicjalizować NULL-em i nie wpłynie to negatywnie na działanie programu?
Nie, a będzie bezpieczniej. W przypadku operacji na pustym wskaźniku wyłoży się
aplikacja, a w przypadku gdy wskaźnik pokazuje gdzieś, może zdarzyć się "tragedia".

edit: stosuj
nullptr
P-148454
« 1 »
  Strona 1 z 1