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

[C++] Lista jednokierunkowa

Ostatnio zmodyfikowano 2012-05-04 14:56
Autor Wiadomość
m_rafal
Temat założony przez niniejszego użytkownika
[C++] Lista jednokierunkowa
» 2012-04-30 14:19:21
Witam.
Mam problem z zadaniem, oto jego treść:

Stworzyć klasę Student posiadającą następujące pola:
Imie (String)
Nazwisko (String)
Nr_albumu (integer)
Srednia (float)
Przedmioty (dynamiczna tablica typu String)
Ilosc_przedmiotow (integer)
Na początku programu użytkownik podaje liczbę tworzonych
obiektów K i zostaje przydzielona pamięć na tablicę K obiektów
typu Student. Następnie należy wczytać dane poszczególnego
Obiektu z klawiatury. W czasie wczytywania każdego obiektu
powinno znaleźć się zapytanie o ilość Przedmiotów N dla danego
obiektu Student, a następnie dynamicznie przydzielona pamięć
na N Przedmiotów oraz ich wczytanie. Należy stworzyć Menu umożliwiające:
a) Dodanie i wprowadzenie danych nowego studenta (zwiększając
pamięć o 1 obiekt klasy student),
b) Wyświetlenie aktualnie zapisanych studentów,
c) Skasowanie całej zawartości i zakończenie programu.


Używam Visual Studio 2010 Ultimate. Mój problem tkwi w dodawaniu studentów i w ich wyświetlaniu. Gdy dodam x studentów, wyświetla mi tylko pierwszego i ostatniego. Wniosek: musi być gdzieś błąd w powiązaniu tych elementów w listę, bądź z funkcją wyświetl jest coś nie tak. Rozumiem idee listy jednokierunkowej, kiedyś robiłem coś podobnego i wszystko grało, jednak teraz siedzę nad tym od dwóch dni i nie mogę rozwikłać, gdzie jest kruczek. Proszę uprzejmie o jakiekolwiek wskazówki, jeśli coś będzie niejasne w kodzie, pytać.
Pozdrawiam serdecznie.


DEFINICJA KLASY:
C/C++
#include<iostream>
using namespace std;
#include<string>
#pragma once
class Student
{
public:
   
    Student( void );
    ~Student( void );
    void Wypelnij();
    void PokazDaneOsoby();
    void WyswietlWszystko( Student * pierwszy, Student * pomocny );
    void DodajStudenta( Student * pomocniczy, Student * poczatkowy, int & liczn );
    void UsunWszystko( Student * pomoc, Student * poczatek );
    Student * nast;
    Student * dodany;
private:
   
    string Imie;
    string Nazwisko;
    int Nr_albumu;
    float Srednia;
    int Ilosc_przedmiotow;
    string * Przedmioty;
   
};

DEFINICJA FUNKCJI KLASY:
C/C++
#include "StdAfx.h"
#include "Student.h"


Student::Student( void )
{
}


Student::~Student( void )
{
}
void Student::Wypelnij()
{
   
   
    cout << "Podaj imie: "; cout << "\n";
    cin >> Imie; cout << "\n";
    cout << "Podaj nazwisko: "; cout << "\n";
    cin >> Nazwisko; cout << "\n";
    cout << "Podaj numer albumu: "; cout << "\n";
    cin >> Nr_albumu; cout << "\n";
    cout << "Podaj ilosc przedmiotow: "; cout << "\n";
    cin >> Ilosc_przedmiotow; cout << "\n";
    cout << "Podaj srednia studenta: "; cout << "\n";
    cin >> Srednia; cout << "\n";
   
   
    Przedmioty = new string[ Ilosc_przedmiotow ];
   
    for( int i = 0; i < Ilosc_przedmiotow; i++ )
   
    {
        cout << "Podaj " << i + 1 << " przedmiot" << endl;
       
        cin >> Przedmioty[ i ];
       
    }
   
}

void Student::PokazDaneOsoby()
{
    cout << Imie << "\t";
    cout << Nazwisko << "\t";
    cout << Nr_albumu << "\t";
    cout << Ilosc_przedmiotow << "\t";
    cout << Srednia << "\t";
    cout << "Przedmioty: ";
   
    for( int i = 0; i < Ilosc_przedmiotow; i++ )
    {
        cout << Przedmioty[ i ] << ",";
    }
}

void Student::DodajStudenta( Student * pomocniczy, Student * poczatkowy, int & liczn )
{
   
    if( liczn == 0 )
    { pomocniczy = poczatkowy;
        pomocniczy->nast = new Student;
        nast->Wypelnij();
        nast->nast = NULL;
        pomocniczy = nast;
        liczn = 1; cout << "\nPowiazalismy dwa elementy\n";
    }
    else if( liczn == 1 )
    {
        cout << "\nTeraz wypelniamy w petli\n";
        pomocniczy = poczatkowy;
        while( pomocniczy->nast != NULL )
             pomocniczy = pomocniczy->nast; // Po wyjsciu z petli bedziemy miec pomocniczny na ostatni element
       
        pomocniczy->nast = new Student;
        nast->Wypelnij();
        nast->nast = NULL;
       
       
    }
   
}

void Student::WyswietlWszystko( Student * pierwszy, Student * pomocny )
{
   
   
    pomocny = pierwszy;
    while( pomocny )
    {
        cout << "\n\n";
        pomocny->PokazDaneOsoby();
        pomocny = pomocny->nast;
        cout << "\n\n";
       
    }
   
   
}

void Student::UsunWszystko( Student * pomoc, Student * poczatek )
{
   
    while( poczatek ) // dopóki nie został osiągnięty koniec listy
    {
        pomoc = poczatek; // pomoc wskazuje na początek listy
        poczatek = poczatek->nast; // przejdź listą do następnego elementu
        delete pomoc;
    }

PLIK GłÓWNY:
C/C++
// LAB2jeszcze.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Student.h"

int _tmain( int argc, _TCHAR * argv[] )
{
    int licznik = 0;
    int licznik2 = 0;
    Student * nowy;
    Student * poczatek;
    Student * pomoc = NULL;
    Student * tab;
   
    int rozmtab, instrukcja;
   
    /*cout <<  "Podaj rozmiar tablicy typu Student:\n";
                    cin  >>  rozmtab; cout<<"\n";
   
                    nowy=new Student[rozmtab];
                   
                   
                    for(int i=0;i<rozmtab;i++)
                            {
                                    tab[i].Wypelnij();
                            }*/
    /*poczatek=&(nowy[rozmtab]);
            poczatek->nast=NULL;*/
   
   
    while( 1 )
    {
       
       
        cout << "                             ||| MENU ||| \n\n\n"
        << "(1) Dodanie i wprowadzenie danych nowego studenta \n\n"
        << "(2) Wyswietlenie studentow \n\n"
        << "(3) Skasowanie studentow i zakonczenie programu \n\n";
        cin >> instrukcja;
       
        switch( instrukcja )
       
        {
        case 1: if( licznik == 0 )
            {
                cout << "\nTworzymy dla licznika rownego zero i ustalamy poczatek listy \n\n";
                nowy = new Student; // pierwszy element
                poczatek = nowy; // tutaj mamy poczatek listy - wskaznik poczatek pokazuje na pierwszy obiekt listy
                poczatek->Wypelnij();
                poczatek->nast = NULL;
                licznik = 1; break;
            }
            else poczatek->DodajStudenta( pomoc, poczatek, licznik2 ); break;
           
        case 2: poczatek->WyswietlWszystko( poczatek, pomoc ); break;
           
        case 3: poczatek->UsunWszystko( pomoc, poczatek ); break;
           
            default: cout << " Opcja pod tym numerem nie istnieje\n"; break;
           
        }
       
        if( instrukcja == 3 ) break;
       
    }
   
   
    cin.ignore();
    getchar();
    return 0;
}
P-55666
SeaMonster131
» 2012-04-30 14:21:43
Wklej kod na forum:
[cpp] kod [/cpp]
P-55667
Admixior
» 2012-04-30 21:25:34
Nie jestem pewien czy w tym tkwi problem:
C/C++
else if( liczn == 1 )
{
    cout << "\nTeraz wypelniamy w petli\n";
    pomocniczy = poczatkowy;
    while( pomocniczy->nast != NULL )
         pomocniczy = pomocniczy->nast; // Po wyjsciu z petli bedziemy miec pomocniczny na ostatni element
   
    pomocniczy->nast = new Student;
    nast->Wypelnij(); //tutaj
    nast->nast = NULL; //i utaj
   
   
}

ujmę to dobitniej:
C/C++
else if( liczn == 1 )
{
    cout << "\nTeraz wypelniamy w petli\n";
    pomocniczy = poczatkowy;
    while( pomocniczy->nast != NULL )
         pomocniczy = pomocniczy->nast; // Po wyjsciu z petli bedziemy miec pomocniczny na ostatni element
   
    pomocniczy->nast = new Student;
    this->nast->Wypelnij();
    this->nast->nast = NULL;
    //gdzie this to jest (wiesz co) pierwszy element...
   
}

powinno być wg. mnie (nie czytałem całego kodu tylko kawałek):
C/C++
pomocniczy->nast->Wypelnij();
pomocniczy->nast->nast = NULL;
P-55699
m_rafal
Temat założony przez niniejszego użytkownika
» 2012-05-04 14:56:10
Trafiłeś w sedno, tu tkwił problem. This to oczywiście specjalny wskaźnik, który jest inicjalizowany adresem konkretnego obiektu danej klasy. W pliku nagłówkowym jest zdefiniowany właśnie wskaźnik nast, niezbędny do stworzenia listy jednokierunkowej ( ostatni element listy pokazuje na NULL ). Brakowało informacji, do którego obiektu typu Student, należy wskaźnik nast. Dziękuje za pomoc.
P-55998
« 1 »
  Strona 1 z 1